]> git.pld-linux.org Git - packages/gcc.git/blob - gcc32-tls-dwarf2.patch
- updated for 3.3.3
[packages/gcc.git] / gcc32-tls-dwarf2.patch
1 2002-08-21  Richard Henderson  <rth@redhat.com>
2
3         * config/i386/i386-protos.h (i386_output_dwarf_dtprel): Add
4         prototype.
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.
17
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));
22  
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));
26  
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)
31    fputc ('\n', file);
32  }
33  
34 +/* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
35 +   We need to emit DTP-relative relocations.  */
36 +
37 +void
38 +i386_output_dwarf_dtprel (file, size, x)
39 +     FILE *file;
40 +     int size;
41 +     rtx x;
42 +{
43 +  switch (size)
44 +    {
45 +    case 4:
46 +      fputs (ASM_LONG, file);
47 +      break;
48 +    case 8:
49 +#ifdef ASM_QUAD
50 +      fputs (ASM_QUAD, file);
51 +      break;
52 +#endif
53 +    default:
54 +      abort ();
55 +   }
56 +  
57 +  output_addr_const (file, x);
58 +  fputs ("@DTPOFF", file);
59 +}
60 +
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)
69  
70 +/* Emit a dtp-relative reference to a TLS variable.  */
71 +
72 +#ifdef HAVE_AS_TLS
73 +#define ASM_OUTPUT_DWARF_DTPREL(FILE, SIZE, X) \
74 +  i386_output_dwarf_dtprel (FILE, SIZE, X)
75 +#endif
76 +
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,
84      DW_OP_call2 = 0x98,
85      DW_OP_call4 = 0x99,
86 -    DW_OP_calli = 0x9a
87 +    DW_OP_call_ref = 0x9a,
88 +    /* GNU extensions.  */
89 +    DW_OP_GNU_push_tls_address = 0xe0
90    };
91  
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.  */
95  
96  /* Type encodings.  */
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.  */
102  
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)
106 +
107 +
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)
112    switch (op)
113      {
114      case DW_OP_addr:
115 +    case INTERNAL_DW_OP_tls_addr:
116        return "DW_OP_addr";
117      case DW_OP_deref:
118        return "DW_OP_deref";
119 @@ -2583,6 +2589,16 @@ dwarf_stack_op_name (op)
120        return "DW_OP_xderef_size";
121      case DW_OP_nop:
122        return "DW_OP_nop";
123 +    case DW_OP_push_object_address:
124 +      return "DW_OP_push_object_address";
125 +    case DW_OP_call2:
126 +      return "DW_OP_call2";
127 +    case DW_OP_call4:
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";
133      default:
134        return "OP_<unknown>";
135      }
136 @@ -2640,6 +2656,7 @@ size_of_loc_descr (loc)
137    switch (loc->dw_loc_opc)
138      {
139      case DW_OP_addr:
140 +    case INTERNAL_DW_OP_tls_addr:
141        size += DWARF2_ADDR_SIZE;
142        break;
143      case DW_OP_const1u:
144 @@ -2725,6 +2742,15 @@ size_of_loc_descr (loc)
145      case DW_OP_xderef_size:
146        size += 1;
147        break;
148 +    case DW_OP_call2:
149 +      size += 2;
150 +      break;
151 +    case DW_OP_call4:
152 +      size += 4;
153 +      break;
154 +    case DW_OP_call_ref:
155 +      size += DWARF2_ADDR_SIZE;
156 +      break;
157      default:
158        break;
159      }
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);
163        break;
164 +
165 +    case INTERNAL_DW_OP_tls_addr:
166 +#ifdef ASM_OUTPUT_DWARF_DTPREL
167 +      ASM_OUTPUT_DWARF_DTPREL (asm_out_file, DWARF2_ADDR_SIZE,
168 +                              val1->v.val_addr);
169 +      fputc ('\n', asm_out_file);
170 +#else
171 +      abort ();
172 +#endif
173 +      break;
174 +
175      default:
176        /* Other codes have no operands.  */
177        break;
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)
189                : 0);
190  
191      case VAR_DECL:
192 +      if (DECL_THREAD_LOCAL (loc))
193 +       {
194 +         rtx rtl;
195 +
196 +#ifndef ASM_OUTPUT_DWARF_DTPREL
197 +         /* If this is not defined, we have no way to emit the data.  */
198 +         return 0;
199 +#endif
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))
203 +           return 0;
204 +
205 +         rtl = rtl_for_decl_location (loc);
206 +         if (rtl == NULL_RTX)
207 +           return 0;
208 +
209 +         if (GET_CODE (rtl) != MEM)
210 +           return 0;
211 +         rtl = XEXP (rtl, 0);
212 +         if (! CONSTANT_P (rtl))
213 +           return 0;
214 +
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;
218 +
219 +         ret1 = new_loc_descr (DW_OP_GNU_push_tls_address, 0, 0);
220 +         add_loc_descr (&ret, ret1);
221 +
222 +         indirect_p = 1;
223 +         break;
224 +       }
225 +      /* FALLTHRU */
226 +
227      case PARM_DECL:
228        {
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.  */
233  
234 -static void
235 -add_AT_location_description (die, attr_kind, rtl)
236 +static inline void
237 +add_AT_location_description (die, attr_kind, descr)
238       dw_die_ref die;
239       enum dwarf_attribute attr_kind;
240 -     rtx rtl;
241 +     dw_loc_descr_ref descr;
242  {
243 -  dw_loc_descr_ref descr = loc_descriptor (rtl);
244 -
245    if (descr != 0)
246      add_AT_loc (die, attr_kind, descr);
247  }
248 @@ -8963,6 +9034,13 @@ rtl_for_decl_location (decl)
249    if (rtl)
250      rtl = ASM_SIMPLIFY_DWARF_ADDR (rtl);
251  #endif
252 +
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.  */
256 +  if (rtl)
257 +    rtl = avoid_constant_pool_reference (rtl);
258 +
259    return rtl;
260  }
261  
262 @@ -8983,6 +9061,7 @@ add_location_or_const_value_attribute (d
263       tree decl;
264  {
265    rtx rtl;
266 +  dw_loc_descr_ref descr;
267  
268    if (TREE_CODE (decl) == ERROR_MARK)
269      return;
270 @@ -8993,16 +9072,11 @@ add_location_or_const_value_attribute (d
271    if (rtl == NULL_RTX)
272      return;
273  
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);
278 -
279    switch (GET_CODE (rtl))
280      {
281      case ADDRESSOF:
282 -      /* The address of a variable that was optimized away; don't emit
283 -        anything.  */
284 +      /* The address of a variable that was optimized away;
285 +        don't emit anything.  */
286        break;
287  
288      case CONST_INT:
289 @@ -9017,12 +9091,24 @@ add_location_or_const_value_attribute (d
290        break;
291  
292      case MEM:
293 -    case REG:
294 -    case SUBREG:
295 -    case CONCAT:
296 -      add_AT_location_description (die, DW_AT_location, rtl);
297 +      if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
298 +       {
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);
304 +       }
305 +      else
306 +       {
307 +       case REG:
308 +       case SUBREG:
309 +       case CONCAT:
310 +         descr = loc_descriptor (rtl);
311 +       }
312 +      add_AT_location_description (die, DW_AT_location, descr);
313        break;
314 -
315 +       
316      default:
317        abort ();
318      }
319 @@ -9154,7 +9240,8 @@ add_bound_info (subrange_die, bound_attr
320  
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);
327         }
328  
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)));
335  #endif
336      }
337  
This page took 0.064441 seconds and 3 git commands to generate.