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]

Re: ICE with x86, PIC, and dwarf2


On Sat, Jun 26, 1999 at 05:34:29PM -0400, Zack Weinberg wrote:
> What's an UNSPEC doing there, anyway?  It's so print_operand_address in
> i386.c knows to print `__libc_pagesize@GOTOFF' instead of `__libc_pagesize'. 
> Other architectures seem to do this differently.  I'm fairly sure i386 ought
> to do it the way they do; getting the print_operand_address logic into
> dwarf2out would be awful, and dwarf2out doesn't seem to want @GOT/@GOTOFF
> suffixes anyway.

I have a hack for this sitting on a cygnus branch waiting to 
be reviewed.  Here's the raw diffs.

It's pretty gross.  Anyone care to suggest a better way?


r~


date: 1998/10/30 18:49:29;  author: rth;  state: Exp;  lines: +4 -0
        * dwarf2out.c (mem_loc_descriptor): Call ASM_SIMPLIFY_DWARF_ADDR
        if defined.
        * dwarfout.c (output_mem_loc_descriptor): Likewise.
        * i386.c (i386_simplify_dwarf_addr): New.
        * i386.h (ASM_SIMPLIFY_DWARF_ADDR): New.

date: 1998/10/29 00:01:43;  author: rth;  state: Exp;  lines: +22 -18
        * dwarf2out.c (ASM_OUTPUT_DWARF2_ADDR_CONST): Renamed from
        ASM_OUTPUT_DWARF_ADDR_CONST.  Update all callers.
        (dwarf2out_addr_const_to_string): Rename from addr_const_to_string.
        Make public.  Look for ASM_DWARF2_ADDR_CONST_TO_STRING and exit
        if it handles the rtx.
        * dwarf2out.h (dwarf2out_addr_const_to_string): Prototype.

        * i386.c (i386_dwarf1_output_addr_const): New.
        (i386_dwarf2_addr_to_string): New.
        * i386.h (ASM_OUTPUT_DWARF_ADDR_CONST): New.
        (ASM_DWARF2_ADDR_CONST_TO_STRING): New.

Index: dwarf2out.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/dwarf2out.c,v
retrieving revision 1.92.2.1
retrieving revision 1.92.2.3
diff -c -p -d -r1.92.2.1 -r1.92.2.3
*** dwarf2out.c	1998/10/16 08:49:47	1.92.2.1
--- dwarf2out.c	1998/10/30 18:49:29	1.92.2.3
*************** static void dwarf2out_stack_adjust	PROTO
*** 345,352 ****
    } while (0)
  #endif
  
! #ifndef ASM_OUTPUT_DWARF_ADDR_CONST
! #define ASM_OUTPUT_DWARF_ADDR_CONST(FILE,ADDR)				\
    fprintf ((FILE), "\t%s\t%s", UNALIGNED_WORD_ASM_OP, (ADDR))
  #endif
  
--- 345,352 ----
    } while (0)
  #endif
  
! #ifndef ASM_OUTPUT_DWARF2_ADDR_CONST
! #define ASM_OUTPUT_DWARF2_ADDR_CONST(FILE,ADDR)				\
    fprintf ((FILE), "\t%s\t%s", UNALIGNED_WORD_ASM_OP, (ADDR))
  #endif
  
*************** static tree dwarf_last_decl;
*** 2374,2380 ****
  
  /* Forward declarations for functions defined in this file.  */
  
- static void addr_const_to_string	PROTO((char *, rtx));
  static char *addr_to_string		PROTO((rtx));
  static int is_pseudo_reg		PROTO((rtx));
  static tree type_main_variant		PROTO((tree));
--- 2374,2379 ----
*************** static char text_end_label[MAX_ARTIFICIA
*** 2652,2659 ****
     Here, the target of the conversion is a string buffer.  We can't use
     output_addr_const directly, because it writes to a file.  */
  
! static void
! addr_const_to_string (str, x)
       char *str;
       rtx x;
  {
--- 2651,2658 ----
     Here, the target of the conversion is a string buffer.  We can't use
     output_addr_const directly, because it writes to a file.  */
  
! void
! dwarf2out_addr_const_to_string (str, x)
       char *str;
       rtx x;
  {
*************** addr_const_to_string (str, x)
*** 2662,2667 ****
--- 2661,2671 ----
  
  restart:
    str[0] = '\0';
+ #ifdef ASM_DWARF2_ADDR_CONST_TO_STRING
+   if (ASM_DWARF2_ADDR_CONST_TO_STRING (str, x))
+     return;
+ #endif
+ 
    switch (GET_CODE (x))
      {
      case PC:
*************** restart:
*** 2696,2702 ****
      case CONST:
        /* This used to output parentheses around the expression, but that does 
           not work on the 386 (either ATT or BSD assembler).  */
!       addr_const_to_string (buf1, XEXP (x, 0));
        strcat (str, buf1);
        break;
  
--- 2700,2706 ----
      case CONST:
        /* This used to output parentheses around the expression, but that does 
           not work on the 386 (either ATT or BSD assembler).  */
!       dwarf2out_addr_const_to_string (buf1, XEXP (x, 0));
        strcat (str, buf1);
        break;
  
*************** restart:
*** 2724,2745 ****
        /* Some assemblers need integer constants to appear last (eg masm).  */
        if (GET_CODE (XEXP (x, 0)) == CONST_INT)
  	{
! 	  addr_const_to_string (buf1, XEXP (x, 1));
  	  strcat (str, buf1);
  	  if (INTVAL (XEXP (x, 0)) >= 0)
  	    strcat (str, "+");
  
! 	  addr_const_to_string (buf1, XEXP (x, 0));
  	  strcat (str, buf1);
  	}
        else
  	{
! 	  addr_const_to_string (buf1, XEXP (x, 0));
  	  strcat (str, buf1);
  	  if (INTVAL (XEXP (x, 1)) >= 0)
  	    strcat (str, "+");
  
! 	  addr_const_to_string (buf1, XEXP (x, 1));
  	  strcat (str, buf1);
  	}
        break;
--- 2728,2749 ----
        /* Some assemblers need integer constants to appear last (eg masm).  */
        if (GET_CODE (XEXP (x, 0)) == CONST_INT)
  	{
! 	  dwarf2out_addr_const_to_string (buf1, XEXP (x, 1));
  	  strcat (str, buf1);
  	  if (INTVAL (XEXP (x, 0)) >= 0)
  	    strcat (str, "+");
  
! 	  dwarf2out_addr_const_to_string (buf1, XEXP (x, 0));
  	  strcat (str, buf1);
  	}
        else
  	{
! 	  dwarf2out_addr_const_to_string (buf1, XEXP (x, 0));
  	  strcat (str, buf1);
  	  if (INTVAL (XEXP (x, 1)) >= 0)
  	    strcat (str, "+");
  
! 	  dwarf2out_addr_const_to_string (buf1, XEXP (x, 1));
  	  strcat (str, buf1);
  	}
        break;
*************** restart:
*** 2751,2777 ****
        if (GET_CODE (x) != MINUS)
  	goto restart;
  
!       addr_const_to_string (buf1, XEXP (x, 0));
        strcat (str, buf1);
        strcat (str, "-");
        if (GET_CODE (XEXP (x, 1)) == CONST_INT
  	  && INTVAL (XEXP (x, 1)) < 0)
  	{
  	  strcat (str, ASM_OPEN_PAREN);
! 	  addr_const_to_string (buf1, XEXP (x, 1));
  	  strcat (str, buf1);
  	  strcat (str, ASM_CLOSE_PAREN);
  	}
        else
  	{
! 	  addr_const_to_string (buf1, XEXP (x, 1));
  	  strcat (str, buf1);
  	}
        break;
  
      case ZERO_EXTEND:
      case SIGN_EXTEND:
!       addr_const_to_string (buf1, XEXP (x, 0));
        strcat (str, buf1);
        break;
  
--- 2755,2781 ----
        if (GET_CODE (x) != MINUS)
  	goto restart;
  
!       dwarf2out_addr_const_to_string (buf1, XEXP (x, 0));
        strcat (str, buf1);
        strcat (str, "-");
        if (GET_CODE (XEXP (x, 1)) == CONST_INT
  	  && INTVAL (XEXP (x, 1)) < 0)
  	{
  	  strcat (str, ASM_OPEN_PAREN);
! 	  dwarf2out_addr_const_to_string (buf1, XEXP (x, 1));
  	  strcat (str, buf1);
  	  strcat (str, ASM_CLOSE_PAREN);
  	}
        else
  	{
! 	  dwarf2out_addr_const_to_string (buf1, XEXP (x, 1));
  	  strcat (str, buf1);
  	}
        break;
  
      case ZERO_EXTEND:
      case SIGN_EXTEND:
!       dwarf2out_addr_const_to_string (buf1, XEXP (x, 0));
        strcat (str, buf1);
        break;
  
*************** addr_to_string (x)
*** 2788,2794 ****
       rtx x;
  {
    char buf[1024];
!   addr_const_to_string (buf, x);
    return xstrdup (buf);
  }
  
--- 2792,2798 ----
       rtx x;
  {
    char buf[1024];
!   dwarf2out_addr_const_to_string (buf, x);
    return xstrdup (buf);
  }
  
*************** output_loc_operands (loc)
*** 5046,5052 ****
    switch (loc->dw_loc_opc)
      {
      case DW_OP_addr:
!       ASM_OUTPUT_DWARF_ADDR_CONST (asm_out_file, val1->v.val_addr);
        fputc ('\n', asm_out_file);
        break;
      case DW_OP_const1u:
--- 5050,5056 ----
    switch (loc->dw_loc_opc)
      {
      case DW_OP_addr:
!       ASM_OUTPUT_DWARF2_ADDR_CONST (asm_out_file, val1->v.val_addr);
        fputc ('\n', asm_out_file);
        break;
      case DW_OP_const1u:
*************** output_die (die)
*** 5195,5202 ****
        switch (a->dw_attr_val.val_class)
  	{
  	case dw_val_class_addr:
! 	  ASM_OUTPUT_DWARF_ADDR_CONST (asm_out_file,
! 				       a->dw_attr_val.v.val_addr);
  	  break;
  
  	case dw_val_class_loc:
--- 5199,5206 ----
        switch (a->dw_attr_val.val_class)
  	{
  	case dw_val_class_addr:
! 	  ASM_OUTPUT_DWARF2_ADDR_CONST (asm_out_file,
! 				        a->dw_attr_val.v.val_addr);
  	  break;
  
  	case dw_val_class_loc:
*************** mem_loc_descriptor (rtl)
*** 6441,6446 ****
--- 6445,6454 ----
       description of here will be the lowest numbered location which is
       actually within the array.  That's *not* necessarily the same as the
       zeroth element of the array.  */
+ 
+ #ifdef ASM_SIMPLIFY_DWARF_ADDR
+   rtl = ASM_SIMPLIFY_DWARF_ADDR(rtl);
+ #endif
  
    switch (GET_CODE (rtl))
      {
Index: dwarfout.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/dwarfout.c,v
retrieving revision 1.85.2.1
retrieving revision 1.85.2.2
diff -c -p -d -r1.85.2.1 -r1.85.2.2
*** dwarfout.c	1998/10/16 08:49:48	1.85.2.1
--- dwarfout.c	1998/10/30 18:49:32	1.85.2.2
*************** output_mem_loc_descriptor (rtl)
*** 1678,1683 ****
--- 1678,1687 ----
       which is actually within the array.  That's *not* necessarily the
       same as the zeroth element of the array.  */
  
+ #ifdef ASM_SIMPLIFY_DWARF_ADDR
+   rtl = ASM_SIMPLIFY_DWARF_ADDR(rtl);
+ #endif
+ 
    switch (GET_CODE (rtl))
      {
        case SUBREG:
Index: i386.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/config/i386/i386.h,v
retrieving revision 1.56.2.5
retrieving revision 1.56.2.7
diff -c -p -d -r1.56.2.5 -r1.56.2.7
*** i386.h	1998/09/28 22:52:27	1.56.2.5
--- i386.h	1998/10/30 18:49:34	1.56.2.7
*************** do { long l;						\
*** 2499,2506 ****
  ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10),	\
    sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
  
- 
- 
  /* This is how to output an assembler line defining an `int' constant.  */
  
  #define ASM_OUTPUT_INT(FILE,VALUE)  \
--- 2499,2504 ----
*************** do { long l;						\
*** 2562,2567 ****
--- 2560,2582 ----
  #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
    fprintf (FILE, "\t.word %s%d-%s%d\n",LPREFIX, VALUE,LPREFIX, REL)
  
+ /* A C statement that outputs an address constant appropriate to 
+    for DWARF debugging.  */
+ 
+ #define ASM_OUTPUT_DWARF_ADDR_CONST(FILE,X) \
+   i386_dwarf1_output_addr_const((FILE),(X))
+ 
+ /* An expression that emits address constant X to STRING.  Returns
+    true if the expression was handled, false otherwise.  */
+ 
+ #define ASM_DWARF2_ADDR_CONST_TO_STRING(STRING,X) \
+   i386_dwarf2_addr_to_string((STRING),(X))
+ 
+ /* Either simplify a location expression, or return the original.  */
+ 
+ #define ASM_SIMPLIFY_DWARF_ADDR(X) \
+   i386_simplify_dwarf_addr(X)
+ 
  /* Define the parentheses used to group arithmetic operations
     in assembler code.  */
  
*************** extern int reg_mentioned_in_mem ();
*** 2784,2789 ****
--- 2799,2807 ----
  extern char *output_int_conditional_move ();
  extern char *output_fp_conditional_move ();
  extern int ix86_can_use_return_insn_p ();
+ extern void i386_dwarf1_output_addr_const ();
+ extern int i386_dwarf2_addr_to_string ();
+ extern struct rtx_def *i386_simplify_dwarf_addr ();
  
  #ifdef NOTYET
  extern struct rtx_def *copy_all_rtx ();
Index: i386.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/config/i386/i386.c,v
retrieving revision 1.65.2.4
retrieving revision 1.65.2.6
diff -c -p -d -r1.65.2.4 -r1.65.2.6
*** i386.c	1998/10/12 22:16:11	1.65.2.4
--- i386.c	1998/10/30 18:49:33	1.65.2.6
*************** output_pic_addr_const (file, x, code)
*** 3205,3210 ****
--- 3205,3292 ----
        output_operand_lossage ("invalid expression as operand");
      }
  }
+ 
+ /* This is called from dwarfout.c via ASM_OUTPUT_DWARF_ADDR_CONST.  
+    We need to handle our special PIC relocations.  */
+ 
+ void 
+ i386_dwarf1_output_addr_const (file, x)
+      FILE *file;
+      rtx x;
+ {
+   fprintf (file, "\t%s\t", INT_ASM_OP);
+   if (flag_pic)
+     output_pic_addr_const (file, x, '\0');
+   else
+     output_addr_const (file, x);
+   fputc ('\n', file);
+ }
+ 
+ /* This is called from dwarf2out.c via ASM_DWARF2_ADDR_CONST_TO_STRING.
+    We need to handle our special PIC relocations.  */
+ 
+ int
+ i386_dwarf2_addr_to_string (str, x)
+      char *str;
+      rtx x;
+ {
+   if (GET_CODE (x) == UNSPEC)
+     {
+       if (XVECLEN (x, 0) != 1)
+ 	abort ();
+ 
+       dwarf2out_addr_const_to_string (str, XVECEXP (x, 0, 0));
+ 
+       switch (XINT (x, 1))
+ 	{
+ 	case 6:
+ 	  strcat (str, "@GOT");
+ 	  break;
+ 	case 7:
+ 	  strcat (str, "@GOTOFF");
+ 	  break;
+ 	case 8:
+ 	  strcat (str, "@PLT");
+ 	  break;
+ 	default:
+ 	  output_operand_lossage ("invalid UNSPEC as operand");
+ 	  break;
+ 	}
+ 
+       return 1;
+     }
+ 
+   return 0;
+ }
+ 
+ /* In the name of slightly smaller debug output, and to cater to
+    general assembler losage, recognize PIC+GOTOFF and turn it back
+    into a direct symbol reference.  */
+ 
+ rtx
+ i386_simplify_dwarf_addr (orig_x)
+      rtx orig_x;
+ {
+   rtx x = orig_x;
+ 
+   if (GET_CODE (x) != PLUS
+       || GET_CODE (XEXP (x, 0)) != REG
+       || GET_CODE (XEXP (x, 1)) != CONST)
+     return orig_x;
+ 
+   x = XEXP (XEXP (x, 1), 0);
+   if (GET_CODE (x) == UNSPEC
+       && XINT (x, 1) == 7)
+     return XVECEXP (x, 0, 0);
+ 
+   if (GET_CODE (x) == PLUS
+       && GET_CODE (XEXP (x, 0)) == UNSPEC
+       && GET_CODE (XEXP (x, 1)) == CONST_INT
+       && XINT (XEXP (x, 0), 1) == 7)
+     return gen_rtx_PLUS (VOIDmode, XVECEXP (XEXP (x, 0), 0, 0), XEXP (x, 1));
+ 
+   return orig_x;
+ }
  
  /* Append the correct conditional move suffix which corresponds to CODE.  */
  


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