1 2002-08-21 Richard Henderson <rth@redhat.com>
3 * config/i386/i386-protos.h (i386_output_dwarf_dtprel): Add
5 * config/i386/i386.c (i386_output_dwarf_dtprel): New.
6 * config/i386/i386.h (ASM_OUTPUT_DWARF_DTPREL): Define.
7 * dwarf2.h (DW_OP_GNU_push_tls_address): Add.
8 (DW_OP_lo_user): Define to 0xe0.
9 * dwarf2out.c (INTERNAL_DW_OP_tls_addr): Define.
10 (dwarf_stack_op_name, sizeof_loc_descr): Handle a few more OPs.
11 (output_loc_operands): Handle INTERNAL_DW_OP_tls_addr.
12 (loc_descriptor_from_tree): Handle DECL_THREAD_LOCAL variables.
13 (add_AT_location_description): Pass descr instead of rtl.
14 (add_location_or_const_value_attribute, add_bound_info,
15 gen_subprogram_die): Adjust its callers.
16 (rtl_for_decl_location): Avoid constant pool references.
18 --- gcc/config/i386/i386-protos.h 20 Aug 2002 17:20:36 -0000 1.1.1.1
19 +++ gcc/config/i386/i386-protos.h 20 Aug 2002 22:35:02 -0000
20 @@ -113,6 +113,7 @@ extern const char *output_fix_trunc PARA
21 extern const char *output_fp_compare PARAMS ((rtx, rtx*, int, int));
23 extern void i386_dwarf_output_addr_const PARAMS ((FILE*, rtx));
24 +extern void i386_output_dwarf_dtprel PARAMS ((FILE*, int, rtx));
25 extern rtx i386_simplify_dwarf_addr PARAMS ((rtx));
27 extern void ix86_expand_clear PARAMS ((rtx));
28 --- gcc/config/i386/i386.c 20 Aug 2002 17:20:36 -0000 1.1.1.1
29 +++ gcc/config/i386/i386.c 20 Aug 2002 22:35:02 -0000
30 @@ -5921,6 +5921,33 @@ i386_dwarf_output_addr_const (file, x)
34 +/* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
35 + We need to emit DTP-relative relocations. */
38 +i386_output_dwarf_dtprel (file, size, x)
46 + fputs (ASM_LONG, file);
50 + fputs (ASM_QUAD, file);
57 + output_addr_const (file, x);
58 + fputs ("@DTPOFF", file);
61 /* In the name of slightly smaller debug output, and to cater to
62 general assembler losage, recognize PIC+GOTOFF and turn it back
63 into a direct symbol reference. */
64 --- gcc/config/i386/i386.h 20 Aug 2002 17:20:36 -0000 1.1.1.1
65 +++ gcc/config/i386/i386.h 20 Aug 2002 22:35:02 -0000
66 @@ -2899,6 +2899,13 @@ extern int const svr4_dbx_register_map[F
67 #define ASM_SIMPLIFY_DWARF_ADDR(X) \
68 i386_simplify_dwarf_addr (X)
70 +/* Emit a dtp-relative reference to a TLS variable. */
73 +#define ASM_OUTPUT_DWARF_DTPREL(FILE, SIZE, X) \
74 + i386_output_dwarf_dtprel (FILE, SIZE, X)
77 /* Switch to init or fini section via SECTION_OP, emit a call to FUNC,
78 and switch back. For x86 we do this only to save a few bytes that
79 would otherwise be unused in the text section. */
80 --- gcc/dwarf2.h 20 Aug 2002 17:20:19 -0000 1.1.1.1
81 +++ gcc/dwarf2.h 20 Aug 2002 22:35:02 -0000
82 @@ -399,10 +399,12 @@ enum dwarf_location_atom
83 DW_OP_push_object_address = 0x97,
87 + DW_OP_call_ref = 0x9a,
88 + /* GNU extensions. */
89 + DW_OP_GNU_push_tls_address = 0xe0
92 -#define DW_OP_lo_user 0x80 /* Implementation-defined range start. */
93 +#define DW_OP_lo_user 0xe0 /* Implementation-defined range start. */
94 #define DW_OP_hi_user 0xff /* Implementation-defined range end. */
97 --- gcc/dwarf2out.c 20 Aug 2002 17:20:19 -0000 1.1.1.1
98 +++ gcc/dwarf2out.c 20 Aug 2002 22:40:42 -0000
99 @@ -2169,6 +2169,11 @@ dwarf2out_frame_finish ()
100 /* And now, the subset of the debugging information support code necessary
101 for emitting location expressions. */
103 +/* We need some way to distinguish DW_OP_addr with a direct symbol
104 + relocation from DW_OP_addr with a dtp-relative symbol relocation. */
105 +#define INTERNAL_DW_OP_tls_addr (0x100 + DW_OP_addr)
108 typedef struct dw_val_struct *dw_val_ref;
109 typedef struct die_struct *dw_die_ref;
110 typedef struct dw_loc_descr_struct *dw_loc_descr_ref;
111 @@ -2294,6 +2299,7 @@ dwarf_stack_op_name (op)
115 + case INTERNAL_DW_OP_tls_addr:
118 return "DW_OP_deref";
119 @@ -2583,6 +2589,16 @@ dwarf_stack_op_name (op)
120 return "DW_OP_xderef_size";
123 + case DW_OP_push_object_address:
124 + return "DW_OP_push_object_address";
126 + return "DW_OP_call2";
128 + return "DW_OP_call4";
129 + case DW_OP_call_ref:
130 + return "DW_OP_call_ref";
131 + case DW_OP_GNU_push_tls_address:
132 + return "DW_OP_GNU_push_tls_address";
134 return "OP_<unknown>";
136 @@ -2640,6 +2656,7 @@ size_of_loc_descr (loc)
137 switch (loc->dw_loc_opc)
140 + case INTERNAL_DW_OP_tls_addr:
141 size += DWARF2_ADDR_SIZE;
144 @@ -2725,6 +2742,15 @@ size_of_loc_descr (loc)
145 case DW_OP_xderef_size:
154 + case DW_OP_call_ref:
155 + size += DWARF2_ADDR_SIZE;
160 @@ -2874,6 +2900,17 @@ output_loc_operands (loc)
161 case DW_OP_xderef_size:
162 dw2_asm_output_data (1, val1->v.val_int, NULL);
165 + case INTERNAL_DW_OP_tls_addr:
166 +#ifdef ASM_OUTPUT_DWARF_DTPREL
167 + ASM_OUTPUT_DWARF_DTPREL (asm_out_file, DWARF2_ADDR_SIZE,
169 + fputc ('\n', asm_out_file);
176 /* Other codes have no operands. */
178 @@ -3598,7 +3635,8 @@ static unsigned int simple_field_decl_al
179 static unsigned HOST_WIDE_INT simple_type_size_in_bits PARAMS ((tree));
180 static HOST_WIDE_INT field_byte_offset PARAMS ((tree));
181 static void add_AT_location_description PARAMS ((dw_die_ref,
182 - enum dwarf_attribute, rtx));
183 + enum dwarf_attribute,
184 + dw_loc_descr_ref));
185 static void add_data_member_location_attribute PARAMS ((dw_die_ref, tree));
186 static void add_const_value_attribute PARAMS ((dw_die_ref, rtx));
187 static rtx rtl_for_decl_location PARAMS ((tree));
188 @@ -8031,6 +8069,41 @@ loc_descriptor_from_tree (loc, addressp)
192 + if (DECL_THREAD_LOCAL (loc))
196 +#ifndef ASM_OUTPUT_DWARF_DTPREL
197 + /* If this is not defined, we have no way to emit the data. */
200 + /* The way DW_OP_GNU_push_tls_address is specified, we can only
201 + look up addresses of objects in the current module. */
202 + if (DECL_P (loc) && TREE_PUBLIC (loc) && !MODULE_LOCAL_P (loc))
205 + rtl = rtl_for_decl_location (loc);
206 + if (rtl == NULL_RTX)
209 + if (GET_CODE (rtl) != MEM)
211 + rtl = XEXP (rtl, 0);
212 + if (! CONSTANT_P (rtl))
215 + ret = new_loc_descr (INTERNAL_DW_OP_tls_addr, 0, 0);
216 + ret->dw_loc_oprnd1.val_class = dw_val_class_addr;
217 + ret->dw_loc_oprnd1.v.val_addr = rtl;
219 + ret1 = new_loc_descr (DW_OP_GNU_push_tls_address, 0, 0);
220 + add_loc_descr (&ret, ret1);
229 rtx rtl = rtl_for_decl_location (loc);
230 @@ -8531,14 +8604,12 @@ field_byte_offset (decl)
231 whole parameters. Note that the location attributes for struct fields are
232 generated by the routine `data_member_location_attribute' below. */
235 -add_AT_location_description (die, attr_kind, rtl)
237 +add_AT_location_description (die, attr_kind, descr)
239 enum dwarf_attribute attr_kind;
241 + dw_loc_descr_ref descr;
243 - dw_loc_descr_ref descr = loc_descriptor (rtl);
246 add_AT_loc (die, attr_kind, descr);
248 @@ -8963,6 +9034,13 @@ rtl_for_decl_location (decl)
250 rtl = ASM_SIMPLIFY_DWARF_ADDR (rtl);
253 + /* If we don't look past the constant pool, we risk emitting a
254 + reference to a constant pool entry that isn't referenced from
255 + code, and thus is not emitted. */
257 + rtl = avoid_constant_pool_reference (rtl);
262 @@ -8983,6 +9061,7 @@ add_location_or_const_value_attribute (d
266 + dw_loc_descr_ref descr;
268 if (TREE_CODE (decl) == ERROR_MARK)
270 @@ -8993,16 +9072,11 @@ add_location_or_const_value_attribute (d
274 - /* If we don't look past the constant pool, we risk emitting a
275 - reference to a constant pool entry that isn't referenced from
276 - code, and thus is not emitted. */
277 - rtl = avoid_constant_pool_reference (rtl);
279 switch (GET_CODE (rtl))
282 - /* The address of a variable that was optimized away; don't emit
284 + /* The address of a variable that was optimized away;
285 + don't emit anything. */
289 @@ -9017,12 +9091,24 @@ add_location_or_const_value_attribute (d
296 - add_AT_location_description (die, DW_AT_location, rtl);
297 + if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
299 + /* Need loc_descriptor_from_tree since that's where we know
300 + how to handle TLS variables. Want the object's address
301 + since the top-level DW_AT_location assumes such. See
302 + the confusion in loc_descriptor for reference. */
303 + descr = loc_descriptor_from_tree (decl, 1);
310 + descr = loc_descriptor (rtl);
312 + add_AT_location_description (die, DW_AT_location, descr);
319 @@ -9154,7 +9240,8 @@ add_bound_info (subrange_die, bound_attr
321 add_AT_flag (decl_die, DW_AT_artificial, 1);
322 add_type_attribute (decl_die, TREE_TYPE (bound), 1, 0, ctx);
323 - add_AT_location_description (decl_die, DW_AT_location, loc);
324 + add_AT_location_description (decl_die, DW_AT_location,
325 + loc_descriptor (loc));
326 add_AT_die_ref (subrange_die, bound_attr, decl_die);
329 @@ -10359,7 +10446,7 @@ gen_subprogram_die (decl, context_die)
330 is not part of the state saved/restored for inline functions. */
331 if (current_function_needs_context)
332 add_AT_location_description (subr_die, DW_AT_static_link,
333 - lookup_static_chain (decl));
334 + loc_descriptor (lookup_static_chain (decl)));