Commit b9203463 by Richard Henderson Committed by Richard Henderson

dwarf2.h (DW_OP_call_ref): Rename from DW_OP_calli.

        * dwarf2.h (DW_OP_call_ref): Rename from DW_OP_calli.
        (DW_OP_GNU_push_tls_address): New.
        (DW_OP_lo_user): Fix.
        * dwarf2out.c (INTERNAL_DW_OP_tls_addr): New.
        (dwarf_stack_op_name): Handle it, plus other dwarf3 opcodes.
        (size_of_loc_descr): Likewise.
        (output_loc_operands): Handle INTERNAL_DW_OP_tls_addr.
        (add_AT_location_description): Take a dw_loc_descr_ref not an rtx.
        (loc_descriptor_from_tree): Handle TLS variables.
        (rtl_for_decl_location): Do avoid_constant_pool_reference here ...
        (add_location_or_const_value_attribute): ... not here.  Defer
        to loc_descriptor_from_tree for TLS variables.

        * config/i386/i386.h (ASM_OUTPUT_DWARF_DTPREL): New.
        * config/i386/i386.c (i386_output_dwarf_dtprel): New.
        * config/i386/i386-protos.h: Update.

From-SVN: r56957
parent 7df98878
2002-09-08 Richard Henderson <rth@redhat.com>
* dwarf2.h (DW_OP_call_ref): Rename from DW_OP_calli.
(DW_OP_GNU_push_tls_address): New.
(DW_OP_lo_user): Fix.
* dwarf2out.c (INTERNAL_DW_OP_tls_addr): New.
(dwarf_stack_op_name): Handle it, plus other dwarf3 opcodes.
(size_of_loc_descr): Likewise.
(output_loc_operands): Handle INTERNAL_DW_OP_tls_addr.
(add_AT_location_description): Take a dw_loc_descr_ref not an rtx.
(loc_descriptor_from_tree): Handle TLS variables.
(rtl_for_decl_location): Do avoid_constant_pool_reference here ...
(add_location_or_const_value_attribute): ... not here. Defer
to loc_descriptor_from_tree for TLS variables.
* config/i386/i386.h (ASM_OUTPUT_DWARF_DTPREL): New.
* config/i386/i386.c (i386_output_dwarf_dtprel): New.
* config/i386/i386-protos.h: Update.
2002-09-08 Roger Sayle <roger@eyesopen.com> 2002-09-08 Roger Sayle <roger@eyesopen.com>
PR optimization/6405 PR optimization/6405
......
...@@ -110,6 +110,7 @@ extern const char *output_fix_trunc PARAMS ((rtx, rtx*)); ...@@ -110,6 +110,7 @@ extern const char *output_fix_trunc PARAMS ((rtx, rtx*));
extern const char *output_fp_compare PARAMS ((rtx, rtx*, int, int)); extern const char *output_fp_compare PARAMS ((rtx, rtx*, int, int));
extern void i386_dwarf_output_addr_const PARAMS ((FILE*, rtx)); extern void i386_dwarf_output_addr_const PARAMS ((FILE*, rtx));
extern void i386_output_dwarf_dtprel PARAMS ((FILE*, int, rtx));
extern rtx i386_simplify_dwarf_addr PARAMS ((rtx)); extern rtx i386_simplify_dwarf_addr PARAMS ((rtx));
extern void ix86_expand_clear PARAMS ((rtx)); extern void ix86_expand_clear PARAMS ((rtx));
......
...@@ -5956,6 +5956,33 @@ i386_dwarf_output_addr_const (file, x) ...@@ -5956,6 +5956,33 @@ i386_dwarf_output_addr_const (file, x)
fputc ('\n', file); fputc ('\n', file);
} }
/* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
We need to emit DTP-relative relocations. */
void
i386_output_dwarf_dtprel (file, size, x)
FILE *file;
int size;
rtx x;
{
switch (size)
{
case 4:
fputs (ASM_LONG, file);
break;
case 8:
#ifdef ASM_QUAD
fputs (ASM_QUAD, file);
break;
#endif
default:
abort ();
}
output_addr_const (file, x);
fputs ("@DTPOFF", file);
}
/* In the name of slightly smaller debug output, and to cater to /* In the name of slightly smaller debug output, and to cater to
general assembler losage, recognize PIC+GOTOFF and turn it back general assembler losage, recognize PIC+GOTOFF and turn it back
into a direct symbol reference. */ into a direct symbol reference. */
......
...@@ -3021,6 +3021,13 @@ extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER]; ...@@ -3021,6 +3021,13 @@ extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER];
#define ASM_SIMPLIFY_DWARF_ADDR(X) \ #define ASM_SIMPLIFY_DWARF_ADDR(X) \
i386_simplify_dwarf_addr (X) i386_simplify_dwarf_addr (X)
/* Emit a dtp-relative reference to a TLS variable. */
#ifdef HAVE_AS_TLS
#define ASM_OUTPUT_DWARF_DTPREL(FILE, SIZE, X) \
i386_output_dwarf_dtprel (FILE, SIZE, X)
#endif
/* Switch to init or fini section via SECTION_OP, emit a call to FUNC, /* Switch to init or fini section via SECTION_OP, emit a call to FUNC,
and switch back. For x86 we do this only to save a few bytes that and switch back. For x86 we do this only to save a few bytes that
would otherwise be unused in the text section. */ would otherwise be unused in the text section. */
......
...@@ -399,10 +399,12 @@ enum dwarf_location_atom ...@@ -399,10 +399,12 @@ enum dwarf_location_atom
DW_OP_push_object_address = 0x97, DW_OP_push_object_address = 0x97,
DW_OP_call2 = 0x98, DW_OP_call2 = 0x98,
DW_OP_call4 = 0x99, DW_OP_call4 = 0x99,
DW_OP_calli = 0x9a DW_OP_call_ref = 0x9a,
/* GNU extensions. */
DW_OP_GNU_push_tls_address = 0xe0
}; };
#define DW_OP_lo_user 0x80 /* Implementation-defined range start. */ #define DW_OP_lo_user 0xe0 /* Implementation-defined range start. */
#define DW_OP_hi_user 0xff /* Implementation-defined range end. */ #define DW_OP_hi_user 0xff /* Implementation-defined range end. */
/* Type encodings. */ /* Type encodings. */
......
...@@ -2182,6 +2182,11 @@ dwarf2out_frame_finish () ...@@ -2182,6 +2182,11 @@ dwarf2out_frame_finish ()
/* And now, the subset of the debugging information support code necessary /* And now, the subset of the debugging information support code necessary
for emitting location expressions. */ for emitting location expressions. */
/* We need some way to distinguish DW_OP_addr with a direct symbol
relocation from DW_OP_addr with a dtp-relative symbol relocation. */
#define INTERNAL_DW_OP_tls_addr (0x100 + DW_OP_addr)
typedef struct dw_val_struct *dw_val_ref; typedef struct dw_val_struct *dw_val_ref;
typedef struct die_struct *dw_die_ref; typedef struct die_struct *dw_die_ref;
typedef struct dw_loc_descr_struct *dw_loc_descr_ref; typedef struct dw_loc_descr_struct *dw_loc_descr_ref;
...@@ -2307,6 +2312,7 @@ dwarf_stack_op_name (op) ...@@ -2307,6 +2312,7 @@ dwarf_stack_op_name (op)
switch (op) switch (op)
{ {
case DW_OP_addr: case DW_OP_addr:
case INTERNAL_DW_OP_tls_addr:
return "DW_OP_addr"; return "DW_OP_addr";
case DW_OP_deref: case DW_OP_deref:
return "DW_OP_deref"; return "DW_OP_deref";
...@@ -2596,6 +2602,16 @@ dwarf_stack_op_name (op) ...@@ -2596,6 +2602,16 @@ dwarf_stack_op_name (op)
return "DW_OP_xderef_size"; return "DW_OP_xderef_size";
case DW_OP_nop: case DW_OP_nop:
return "DW_OP_nop"; return "DW_OP_nop";
case DW_OP_push_object_address:
return "DW_OP_push_object_address";
case DW_OP_call2:
return "DW_OP_call2";
case DW_OP_call4:
return "DW_OP_call4";
case DW_OP_call_ref:
return "DW_OP_call_ref";
case DW_OP_GNU_push_tls_address:
return "DW_OP_GNU_push_tls_address";
default: default:
return "OP_<unknown>"; return "OP_<unknown>";
} }
...@@ -2653,6 +2669,7 @@ size_of_loc_descr (loc) ...@@ -2653,6 +2669,7 @@ size_of_loc_descr (loc)
switch (loc->dw_loc_opc) switch (loc->dw_loc_opc)
{ {
case DW_OP_addr: case DW_OP_addr:
case INTERNAL_DW_OP_tls_addr:
size += DWARF2_ADDR_SIZE; size += DWARF2_ADDR_SIZE;
break; break;
case DW_OP_const1u: case DW_OP_const1u:
...@@ -2738,6 +2755,15 @@ size_of_loc_descr (loc) ...@@ -2738,6 +2755,15 @@ size_of_loc_descr (loc)
case DW_OP_xderef_size: case DW_OP_xderef_size:
size += 1; size += 1;
break; break;
case DW_OP_call2:
size += 2;
break;
case DW_OP_call4:
size += 4;
break;
case DW_OP_call_ref:
size += DWARF2_ADDR_SIZE;
break;
default: default:
break; break;
} }
...@@ -2887,6 +2913,17 @@ output_loc_operands (loc) ...@@ -2887,6 +2913,17 @@ output_loc_operands (loc)
case DW_OP_xderef_size: case DW_OP_xderef_size:
dw2_asm_output_data (1, val1->v.val_int, NULL); dw2_asm_output_data (1, val1->v.val_int, NULL);
break; break;
case INTERNAL_DW_OP_tls_addr:
#ifdef ASM_OUTPUT_DWARF_DTPREL
ASM_OUTPUT_DWARF_DTPREL (asm_out_file, DWARF2_ADDR_SIZE,
val1->v.val_addr);
fputc ('\n', asm_out_file);
#else
abort ();
#endif
break;
default: default:
/* Other codes have no operands. */ /* Other codes have no operands. */
break; break;
...@@ -3590,7 +3627,8 @@ static unsigned int simple_decl_align_in_bits PARAMS ((tree)); ...@@ -3590,7 +3627,8 @@ static unsigned int simple_decl_align_in_bits PARAMS ((tree));
static unsigned HOST_WIDE_INT simple_type_size_in_bits PARAMS ((tree)); static unsigned HOST_WIDE_INT simple_type_size_in_bits PARAMS ((tree));
static HOST_WIDE_INT field_byte_offset PARAMS ((tree)); static HOST_WIDE_INT field_byte_offset PARAMS ((tree));
static void add_AT_location_description PARAMS ((dw_die_ref, static void add_AT_location_description PARAMS ((dw_die_ref,
enum dwarf_attribute, rtx)); enum dwarf_attribute,
dw_loc_descr_ref));
static void add_data_member_location_attribute PARAMS ((dw_die_ref, tree)); static void add_data_member_location_attribute PARAMS ((dw_die_ref, tree));
static void add_const_value_attribute PARAMS ((dw_die_ref, rtx)); static void add_const_value_attribute PARAMS ((dw_die_ref, rtx));
static rtx rtl_for_decl_location PARAMS ((tree)); static rtx rtl_for_decl_location PARAMS ((tree));
...@@ -8015,6 +8053,42 @@ loc_descriptor_from_tree (loc, addressp) ...@@ -8015,6 +8053,42 @@ loc_descriptor_from_tree (loc, addressp)
: 0); : 0);
case VAR_DECL: case VAR_DECL:
if (DECL_THREAD_LOCAL (loc))
{
rtx rtl;
#ifndef ASM_OUTPUT_DWARF_DTPREL
/* If this is not defined, we have no way to emit the data. */
return 0;
#endif
/* The way DW_OP_GNU_push_tls_address is specified, we can only
look up addresses of objects in the current module. */
if (! (*targetm.binds_local_p) (loc))
return 0;
rtl = rtl_for_decl_location (loc);
if (rtl == NULL_RTX)
return 0;
if (GET_CODE (rtl) != MEM)
return 0;
rtl = XEXP (rtl, 0);
if (! CONSTANT_P (rtl))
return 0;
ret = new_loc_descr (INTERNAL_DW_OP_tls_addr, 0, 0);
ret->dw_loc_oprnd1.val_class = dw_val_class_addr;
ret->dw_loc_oprnd1.v.val_addr = rtl;
ret1 = new_loc_descr (DW_OP_GNU_push_tls_address, 0, 0);
add_loc_descr (&ret, ret1);
indirect_p = 1;
break;
}
/* FALLTHRU */
case PARM_DECL: case PARM_DECL:
{ {
rtx rtl = rtl_for_decl_location (loc); rtx rtl = rtl_for_decl_location (loc);
...@@ -8497,14 +8571,12 @@ field_byte_offset (decl) ...@@ -8497,14 +8571,12 @@ field_byte_offset (decl)
whole parameters. Note that the location attributes for struct fields are whole parameters. Note that the location attributes for struct fields are
generated by the routine `data_member_location_attribute' below. */ generated by the routine `data_member_location_attribute' below. */
static void static inline void
add_AT_location_description (die, attr_kind, rtl) add_AT_location_description (die, attr_kind, descr)
dw_die_ref die; dw_die_ref die;
enum dwarf_attribute attr_kind; enum dwarf_attribute attr_kind;
rtx rtl; dw_loc_descr_ref descr;
{ {
dw_loc_descr_ref descr = loc_descriptor (rtl);
if (descr != 0) if (descr != 0)
add_AT_loc (die, attr_kind, descr); add_AT_loc (die, attr_kind, descr);
} }
...@@ -8929,6 +9001,13 @@ rtl_for_decl_location (decl) ...@@ -8929,6 +9001,13 @@ rtl_for_decl_location (decl)
if (rtl) if (rtl)
rtl = ASM_SIMPLIFY_DWARF_ADDR (rtl); rtl = ASM_SIMPLIFY_DWARF_ADDR (rtl);
#endif #endif
/* If we don't look past the constant pool, we risk emitting a
reference to a constant pool entry that isn't referenced from
code, and thus is not emitted. */
if (rtl)
rtl = avoid_constant_pool_reference (rtl);
return rtl; return rtl;
} }
...@@ -8949,6 +9028,7 @@ add_location_or_const_value_attribute (die, decl) ...@@ -8949,6 +9028,7 @@ add_location_or_const_value_attribute (die, decl)
tree decl; tree decl;
{ {
rtx rtl; rtx rtl;
dw_loc_descr_ref descr;
if (TREE_CODE (decl) == ERROR_MARK) if (TREE_CODE (decl) == ERROR_MARK)
return; return;
...@@ -8959,16 +9039,11 @@ add_location_or_const_value_attribute (die, decl) ...@@ -8959,16 +9039,11 @@ add_location_or_const_value_attribute (die, decl)
if (rtl == NULL_RTX) if (rtl == NULL_RTX)
return; return;
/* If we don't look past the constant pool, we risk emitting a
reference to a constant pool entry that isn't referenced from
code, and thus is not emitted. */
rtl = avoid_constant_pool_reference (rtl);
switch (GET_CODE (rtl)) switch (GET_CODE (rtl))
{ {
case ADDRESSOF: case ADDRESSOF:
/* The address of a variable that was optimized away; don't emit /* The address of a variable that was optimized away;
anything. */ don't emit anything. */
break; break;
case CONST_INT: case CONST_INT:
...@@ -8983,12 +9058,24 @@ add_location_or_const_value_attribute (die, decl) ...@@ -8983,12 +9058,24 @@ add_location_or_const_value_attribute (die, decl)
break; break;
case MEM: case MEM:
case REG: if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
case SUBREG: {
case CONCAT: /* Need loc_descriptor_from_tree since that's where we know
add_AT_location_description (die, DW_AT_location, rtl); how to handle TLS variables. Want the object's address
since the top-level DW_AT_location assumes such. See
the confusion in loc_descriptor for reference. */
descr = loc_descriptor_from_tree (decl, 1);
}
else
{
case REG:
case SUBREG:
case CONCAT:
descr = loc_descriptor (rtl);
}
add_AT_location_description (die, DW_AT_location, descr);
break; break;
default: default:
abort (); abort ();
} }
...@@ -9120,7 +9207,8 @@ add_bound_info (subrange_die, bound_attr, bound) ...@@ -9120,7 +9207,8 @@ add_bound_info (subrange_die, bound_attr, bound)
add_AT_flag (decl_die, DW_AT_artificial, 1); add_AT_flag (decl_die, DW_AT_artificial, 1);
add_type_attribute (decl_die, TREE_TYPE (bound), 1, 0, ctx); add_type_attribute (decl_die, TREE_TYPE (bound), 1, 0, ctx);
add_AT_location_description (decl_die, DW_AT_location, loc); add_AT_location_description (decl_die, DW_AT_location,
loc_descriptor (loc));
add_AT_die_ref (subrange_die, bound_attr, decl_die); add_AT_die_ref (subrange_die, bound_attr, decl_die);
} }
...@@ -10325,7 +10413,7 @@ gen_subprogram_die (decl, context_die) ...@@ -10325,7 +10413,7 @@ gen_subprogram_die (decl, context_die)
is not part of the state saved/restored for inline functions. */ is not part of the state saved/restored for inline functions. */
if (current_function_needs_context) if (current_function_needs_context)
add_AT_location_description (subr_die, DW_AT_static_link, add_AT_location_description (subr_die, DW_AT_static_link,
lookup_static_chain (decl)); loc_descriptor (lookup_static_chain (decl)));
#endif #endif
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment