This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: ICE with x86, PIC, and dwarf2
- To: Zack Weinberg <zack at rabi dot columbia dot edu>
- Subject: Re: ICE with x86, PIC, and dwarf2
- From: Richard Henderson <rth at cygnus dot com>
- Date: Mon, 28 Jun 1999 19:11:29 -0700
- Cc: egcs-bugs at egcs dot cygnus dot com, egcs-patches at egcs dot cygnus dot com
- References: <199906262134.RAA23735@blastula.phys.columbia.edu>
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. */