diff options
author | Richard Henderson <rth@redhat.com> | 2002-09-08 11:36:54 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2002-09-08 11:36:54 -0700 |
commit | b920346356d7cf23f96d0b5abfca6b43b677bcf5 (patch) | |
tree | 836174b555f80b032094c6faa9d7b90163ee8351 /gcc/dwarf2out.c | |
parent | 7df988780bd6c60725929ffea906fc2e160f94df (diff) | |
download | gcc-b920346356d7cf23f96d0b5abfca6b43b677bcf5.zip gcc-b920346356d7cf23f96d0b5abfca6b43b677bcf5.tar.gz gcc-b920346356d7cf23f96d0b5abfca6b43b677bcf5.tar.bz2 |
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
Diffstat (limited to 'gcc/dwarf2out.c')
-rw-r--r-- | gcc/dwarf2out.c | 128 |
1 files changed, 108 insertions, 20 deletions
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index e8f02e6..5757d24 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -2182,6 +2182,11 @@ dwarf2out_frame_finish () /* And now, the subset of the debugging information support code necessary 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 die_struct *dw_die_ref; typedef struct dw_loc_descr_struct *dw_loc_descr_ref; @@ -2307,6 +2312,7 @@ dwarf_stack_op_name (op) switch (op) { case DW_OP_addr: + case INTERNAL_DW_OP_tls_addr: return "DW_OP_addr"; case DW_OP_deref: return "DW_OP_deref"; @@ -2596,6 +2602,16 @@ dwarf_stack_op_name (op) return "DW_OP_xderef_size"; case 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: return "OP_<unknown>"; } @@ -2653,6 +2669,7 @@ size_of_loc_descr (loc) switch (loc->dw_loc_opc) { case DW_OP_addr: + case INTERNAL_DW_OP_tls_addr: size += DWARF2_ADDR_SIZE; break; case DW_OP_const1u: @@ -2738,6 +2755,15 @@ size_of_loc_descr (loc) case DW_OP_xderef_size: size += 1; 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: break; } @@ -2887,6 +2913,17 @@ output_loc_operands (loc) case DW_OP_xderef_size: dw2_asm_output_data (1, val1->v.val_int, NULL); 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: /* Other codes have no operands. */ break; @@ -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 HOST_WIDE_INT field_byte_offset PARAMS ((tree)); 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_const_value_attribute PARAMS ((dw_die_ref, rtx)); static rtx rtl_for_decl_location PARAMS ((tree)); @@ -8015,6 +8053,42 @@ loc_descriptor_from_tree (loc, addressp) : 0); 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: { rtx rtl = rtl_for_decl_location (loc); @@ -8497,14 +8571,12 @@ field_byte_offset (decl) whole parameters. Note that the location attributes for struct fields are generated by the routine `data_member_location_attribute' below. */ -static void -add_AT_location_description (die, attr_kind, rtl) +static inline void +add_AT_location_description (die, attr_kind, descr) dw_die_ref die; enum dwarf_attribute attr_kind; - rtx rtl; + dw_loc_descr_ref descr; { - dw_loc_descr_ref descr = loc_descriptor (rtl); - if (descr != 0) add_AT_loc (die, attr_kind, descr); } @@ -8929,6 +9001,13 @@ rtl_for_decl_location (decl) if (rtl) rtl = ASM_SIMPLIFY_DWARF_ADDR (rtl); #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; } @@ -8949,6 +9028,7 @@ add_location_or_const_value_attribute (die, decl) tree decl; { rtx rtl; + dw_loc_descr_ref descr; if (TREE_CODE (decl) == ERROR_MARK) return; @@ -8959,16 +9039,11 @@ add_location_or_const_value_attribute (die, decl) if (rtl == NULL_RTX) 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)) { case ADDRESSOF: - /* The address of a variable that was optimized away; don't emit - anything. */ + /* The address of a variable that was optimized away; + don't emit anything. */ break; case CONST_INT: @@ -8983,12 +9058,24 @@ add_location_or_const_value_attribute (die, decl) break; case MEM: - case REG: - case SUBREG: - case CONCAT: - add_AT_location_description (die, DW_AT_location, rtl); + if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl)) + { + /* Need loc_descriptor_from_tree since that's where we know + 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; - + default: abort (); } @@ -9120,7 +9207,8 @@ add_bound_info (subrange_die, bound_attr, bound) add_AT_flag (decl_die, DW_AT_artificial, 1); 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); } @@ -10325,7 +10413,7 @@ gen_subprogram_die (decl, context_die) is not part of the state saved/restored for inline functions. */ if (current_function_needs_context) add_AT_location_description (subr_die, DW_AT_static_link, - lookup_static_chain (decl)); + loc_descriptor (lookup_static_chain (decl))); #endif } |