]>
Commit | Line | Data |
---|---|---|
6ed6bacf AM |
1 | http://sourceware.org/ml/gdb-patches/2011-09/msg00451.html |
2 | Subject: [patch 2/2] Fix DW_OP_GNU_implicit_pointer for DWARF32 v3+ on 64-bit arches | |
3 | ||
4 | Hi, | |
5 | ||
6 | on 64-bit targets DWARF-3+ is used DW_OP_GNU_implicit_pointer does not work. | |
7 | ||
8 | DWARF-2 says: | |
9 | This type of reference (DW_FORM_ref_addr) is the size of an address on | |
10 | the target architecture; | |
11 | DWARF-3 says: | |
12 | 1.5.1 Upward Compatibility | |
13 | References that use the attribute form DW_FORM_ref_addr are specified | |
14 | to be four bytes in the DWARF 32-bit format and eight bytes in the | |
15 | DWARF 64-bit format, while DWARF Version 2 specifies that such | |
16 | references have the same size as an address on the target system (see | |
17 | Sections 7.4 and 7.5.4). | |
18 | ||
19 | (DW_FORM_ref_addr) | |
20 | In the 32-bit DWARF format, this offset is a 4-byte unsigned value; in | |
21 | the 64-bit DWARF format, it is an 8-byte unsigned value (see Section | |
22 | 7.4). | |
23 | ||
24 | GDB currently parsed DW_OP_GNU_implicit_pointer the DWARF-2 way, being | |
25 | incompatible with DWARF-3+. | |
26 | ||
27 | I think DW_OP_GNU_implicit_pointer does not make sense to be used from | |
28 | .debug_frame (DWARF-5 is not yet released to say more) so for .debug_frame its | |
29 | use is just not permitted (the code would be more complicated otherwise). | |
30 | ||
31 | No regressions on {x86_64,x86_64-m32,i686}-fedora16pre-linux-gnu. | |
32 | ||
33 | ||
34 | Thanks, | |
35 | Jan | |
36 | ||
37 | ||
38 | gdb/ | |
39 | 2011-09-26 Jan Kratochvil <jan.kratochvil@redhat.com> | |
40 | ||
41 | Fix DW_OP_GNU_implicit_pointer for DWARF32 v3+ on 64-bit arches. | |
42 | * dwarf2-frame.c (execute_stack_op): Initialize ctx->ref_addr_size. | |
43 | * dwarf2expr.c (execute_stack_op) <DW_OP_GNU_implicit_pointer>: Use | |
44 | ctx->ref_addr_size. Handle its invalid value. | |
45 | * dwarf2expr.h (struct dwarf_expr_context): New field ref_addr_size. | |
46 | * dwarf2loc.c (dwarf2_evaluate_loc_desc_full) | |
47 | (dwarf2_loc_desc_needs_frame): Initialize ctx->ref_addr_size. | |
48 | * dwarf2loc.h (dwarf2_per_cu_ref_addr_size): New declaration. | |
49 | * dwarf2read.c (decode_locdesc): Initialize ctx->ref_addr_size. | |
50 | (dwarf2_per_cu_ref_addr_size): New function. | |
51 | ||
52 | gdb/testsuite/ | |
53 | 2011-09-26 Jan Kratochvil <jan.kratochvil@redhat.com> | |
54 | ||
55 | Fix DW_OP_GNU_implicit_pointer for DWARF32 v3+ on 64-bit arches. | |
56 | * gdb.dwarf2/implptr-64bit.S: New file. | |
57 | * gdb.dwarf2/implptr-64bit.exp: New file. | |
58 | ||
59 | Index: gdb-7.3/gdb/dwarf2-frame.c | |
60 | =================================================================== | |
61 | --- gdb-7.3.orig/gdb/dwarf2-frame.c 2011-03-18 19:52:30.000000000 +0100 | |
62 | +++ gdb-7.3/gdb/dwarf2-frame.c 2011-09-26 22:38:52.000000000 +0200 | |
63 | @@ -397,6 +397,7 @@ execute_stack_op (const gdb_byte *exp, U | |
64 | ||
65 | ctx->gdbarch = get_frame_arch (this_frame); | |
66 | ctx->addr_size = addr_size; | |
67 | + ctx->ref_addr_size = -1; | |
68 | ctx->offset = offset; | |
69 | ctx->baton = this_frame; | |
70 | ctx->read_reg = read_reg; | |
71 | Index: gdb-7.3/gdb/dwarf2expr.c | |
72 | =================================================================== | |
73 | --- gdb-7.3.orig/gdb/dwarf2expr.c 2011-09-26 22:38:34.000000000 +0200 | |
74 | +++ gdb-7.3/gdb/dwarf2expr.c 2011-09-26 22:38:52.000000000 +0200 | |
75 | @@ -539,10 +539,14 @@ execute_stack_op (struct dwarf_expr_cont | |
76 | ULONGEST die; | |
77 | LONGEST len; | |
78 | ||
79 | + if (ctx->ref_addr_size == -1) | |
80 | + error (_("DWARF-2 expression error: DW_OP_GNU_implicit_pointer " | |
81 | + "is not allowed in frame context")); | |
82 | + | |
83 | /* The referred-to DIE. */ | |
84 | - ctx->len = extract_unsigned_integer (op_ptr, ctx->addr_size, | |
85 | + ctx->len = extract_unsigned_integer (op_ptr, ctx->ref_addr_size, | |
86 | byte_order); | |
87 | - op_ptr += ctx->addr_size; | |
88 | + op_ptr += ctx->ref_addr_size; | |
89 | ||
90 | /* The byte offset into the data. */ | |
91 | op_ptr = read_sleb128 (op_ptr, op_end, &len); | |
92 | Index: gdb-7.3/gdb/dwarf2expr.h | |
93 | =================================================================== | |
94 | --- gdb-7.3.orig/gdb/dwarf2expr.h 2011-09-26 22:38:34.000000000 +0200 | |
95 | +++ gdb-7.3/gdb/dwarf2expr.h 2011-09-26 22:38:52.000000000 +0200 | |
96 | @@ -78,6 +78,10 @@ struct dwarf_expr_context | |
97 | /* Target address size in bytes. */ | |
98 | int addr_size; | |
99 | ||
100 | + /* DW_FORM_ref_addr size in bytes. If -1 DWARF is executed from a frame | |
101 | + context and operations depending on DW_FORM_ref_addr are not allowed. */ | |
102 | + int ref_addr_size; | |
103 | + | |
104 | /* Offset used to relocate DW_OP_addr argument. */ | |
105 | CORE_ADDR offset; | |
106 | ||
107 | Index: gdb-7.3/gdb/dwarf2loc.c | |
108 | =================================================================== | |
109 | --- gdb-7.3.orig/gdb/dwarf2loc.c 2011-09-26 22:38:34.000000000 +0200 | |
110 | +++ gdb-7.3/gdb/dwarf2loc.c 2011-09-26 22:39:12.000000000 +0200 | |
111 | @@ -372,6 +372,7 @@ dwarf_expr_prep_ctx (struct frame_info * | |
112 | ||
113 | ctx->gdbarch = get_objfile_arch (objfile); | |
114 | ctx->addr_size = dwarf2_per_cu_addr_size (per_cu); | |
115 | + ctx->ref_addr_size = dwarf2_per_cu_ref_addr_size (per_cu); | |
116 | ctx->offset = dwarf2_per_cu_text_offset (per_cu); | |
117 | ctx->baton = &baton; | |
118 | ctx->read_reg = dwarf_expr_read_reg; | |
119 | @@ -1507,6 +1508,7 @@ dwarf2_loc_desc_needs_frame (const gdb_b | |
120 | ||
121 | ctx->gdbarch = get_objfile_arch (objfile); | |
122 | ctx->addr_size = dwarf2_per_cu_addr_size (per_cu); | |
123 | + ctx->ref_addr_size = dwarf2_per_cu_ref_addr_size (per_cu); | |
124 | ctx->offset = dwarf2_per_cu_text_offset (per_cu); | |
125 | ctx->baton = &baton; | |
126 | ctx->read_reg = needs_frame_read_reg; | |
127 | Index: gdb-7.3/gdb/dwarf2loc.h | |
128 | =================================================================== | |
129 | --- gdb-7.3.orig/gdb/dwarf2loc.h 2011-09-26 22:38:34.000000000 +0200 | |
130 | +++ gdb-7.3/gdb/dwarf2loc.h 2011-09-26 22:38:52.000000000 +0200 | |
131 | @@ -39,6 +39,10 @@ struct objfile *dwarf2_per_cu_objfile (s | |
132 | /* Return the address size given in the compilation unit header for CU. */ | |
133 | CORE_ADDR dwarf2_per_cu_addr_size (struct dwarf2_per_cu_data *cu); | |
134 | ||
135 | +/* Return the DW_FORM_ref_addr size given in the compilation unit header for | |
136 | + CU. */ | |
137 | +int dwarf2_per_cu_ref_addr_size (struct dwarf2_per_cu_data *cu); | |
138 | + | |
139 | /* Return the offset size given in the compilation unit header for CU. */ | |
140 | int dwarf2_per_cu_offset_size (struct dwarf2_per_cu_data *cu); | |
141 | ||
142 | Index: gdb-7.3/gdb/dwarf2read.c | |
143 | =================================================================== | |
144 | --- gdb-7.3.orig/gdb/dwarf2read.c 2011-09-26 22:38:38.000000000 +0200 | |
145 | +++ gdb-7.3/gdb/dwarf2read.c 2011-09-26 22:38:52.000000000 +0200 | |
146 | @@ -15277,6 +15277,22 @@ dwarf2_per_cu_offset_size (struct dwarf2 | |
147 | return cu_headerp->offset_size; | |
148 | } | |
149 | ||
150 | +/* See its dwarf2loc.h declaration. */ | |
151 | + | |
152 | +int | |
153 | +dwarf2_per_cu_ref_addr_size (struct dwarf2_per_cu_data *per_cu) | |
154 | +{ | |
155 | + struct comp_unit_head cu_header_local; | |
156 | + const struct comp_unit_head *cu_headerp; | |
157 | + | |
158 | + cu_headerp = per_cu_header_read_in (&cu_header_local, per_cu); | |
159 | + | |
160 | + if (cu_headerp->version == 2) | |
161 | + return cu_headerp->addr_size; | |
162 | + else | |
163 | + return cu_headerp->offset_size; | |
164 | +} | |
165 | + | |
166 | /* Return the text offset of the CU. The returned offset comes from | |
167 | this CU's objfile. If this objfile came from a separate debuginfo | |
168 | file, then the offset may be different from the corresponding | |
169 | Index: gdb-7.3/gdb/testsuite/gdb.dwarf2/implptr-64bit.S | |
170 | =================================================================== | |
171 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | |
172 | +++ gdb-7.3/gdb/testsuite/gdb.dwarf2/implptr-64bit.S 2011-09-26 22:38:52.000000000 +0200 | |
173 | @@ -0,0 +1,197 @@ | |
174 | +/* Copyright 2010, 2011 Free Software Foundation, Inc. | |
175 | + | |
176 | + This program is free software; you can redistribute it and/or modify | |
177 | + it under the terms of the GNU General Public License as published by | |
178 | + the Free Software Foundation; either version 3 of the License, or | |
179 | + (at your option) any later version. | |
180 | + | |
181 | + This program is distributed in the hope that it will be useful, | |
182 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
183 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
184 | + GNU General Public License for more details. | |
185 | + | |
186 | + You should have received a copy of the GNU General Public License | |
187 | + along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
188 | + | |
189 | + .section .debug_info | |
190 | +d: | |
191 | + /* Length of Compilation Unit Info */ | |
192 | +#if OFFSET_SIZE == 4 | |
193 | +# define OFFSET .4byte | |
194 | + .4byte debug_end - 1f | |
195 | +#elif OFFSET_SIZE == 8 | |
196 | +# define OFFSET .8byte | |
197 | + .4byte 0xffffffff | |
198 | + .8byte debug_end - 1f | |
199 | +#else | |
200 | +# error | |
201 | +#endif | |
202 | +#if ADDR_SIZE == 4 | |
203 | +# define ADDR .4byte | |
204 | +#elif ADDR_SIZE == 8 | |
205 | +# define ADDR .8byte | |
206 | +#else | |
207 | +# error | |
208 | +#endif | |
209 | +#if REF_ADDR_SIZE == 4 | |
210 | +# define REF_ADDR .4byte | |
211 | +#elif REF_ADDR_SIZE == 8 | |
212 | +# define REF_ADDR .8byte | |
213 | +#else | |
214 | +# error | |
215 | +#endif | |
216 | +1: | |
217 | + .2byte DWARF_VERSION /* DWARF version number */ | |
218 | + OFFSET .Ldebug_abbrev0 /* Offset Into Abbrev. Section */ | |
219 | + .byte ADDR_SIZE /* Pointer Size (in bytes) */ | |
220 | + | |
221 | + .uleb128 0x1 /* (DIE (0xb) DW_TAG_compile_unit) */ | |
222 | + .ascii "GNU C 4.4.3\0" /* DW_AT_producer */ | |
223 | + .byte 0x1 /* DW_AT_language */ | |
224 | + .ascii "1.c\0" /* DW_AT_name */ | |
225 | + | |
226 | +.Ltype_int: | |
227 | + .uleb128 0x7 /* DW_TAG_base_type */ | |
228 | + .byte 0x4 /* DW_AT_byte_size */ | |
229 | + .byte 0x5 /* DW_AT_encoding */ | |
230 | + .ascii "int\0" /* DW_AT_name */ | |
231 | + | |
232 | +.Ltype_struct: | |
233 | + .uleb128 0x2 /* DW_TAG_structure_type */ | |
234 | + .ascii "s\0" /* DW_AT_name */ | |
235 | + .byte 4 /* DW_AT_byte_size */ | |
236 | + | |
237 | + .uleb128 0x3 /* DW_TAG_member */ | |
238 | + .ascii "f\0" /* DW_AT_name */ | |
239 | + .4byte .Ltype_int - d /* DW_AT_type */ | |
240 | + .byte 0 /* DW_AT_data_member_location */ | |
241 | + | |
242 | + .byte 0x0 /* end of children of DW_TAG_structure_type */ | |
243 | + | |
244 | + .uleb128 6 /* Abbrev: DW_TAG_subprogram */ | |
245 | + .ascii "main\0" /* DW_AT_name */ | |
246 | + ADDR main /* DW_AT_low_pc */ | |
247 | + ADDR main + 0x100 /* DW_AT_high_pc */ | |
248 | + .4byte .Ltype_int - d /* DW_AT_type */ | |
249 | + .byte 1 /* DW_AT_external */ | |
250 | + | |
251 | +.Ltype_structptr: | |
252 | + .uleb128 0x5 /* DW_TAG_pointer_type */ | |
253 | + .byte ADDR_SIZE /* DW_AT_byte_size */ | |
254 | + .4byte .Ltype_struct - d /* DW_AT_type */ | |
255 | + | |
256 | +.Lvar_out: | |
257 | + .uleb128 0x4 /* (DW_TAG_variable) */ | |
258 | + .ascii "v\0" /* DW_AT_name */ | |
259 | + .byte 2f - 1f /* DW_AT_location: DW_FORM_block1 */ | |
260 | +1: | |
261 | + .byte 0x9e /* DW_OP_implicit_value */ | |
262 | + .uleb128 2f - 3f | |
263 | +3: | |
264 | + .byte 1, 1, 1, 1 | |
265 | +2: | |
266 | + .4byte .Ltype_struct - d /* DW_AT_type */ | |
267 | + | |
268 | + .uleb128 0x4 /* (DW_TAG_variable) */ | |
269 | + .ascii "p\0" /* DW_AT_name */ | |
270 | + .byte 2f - 1f /* DW_AT_location: DW_FORM_block1 */ | |
271 | +1: | |
272 | + .byte 0xf2 /* DW_OP_GNU_implicit_pointer */ | |
273 | + REF_ADDR .Lvar_out - d /* referenced DIE */ | |
274 | + .sleb128 0 /* offset */ | |
275 | +2: | |
276 | + .4byte .Ltype_structptr - d /* DW_AT_type */ | |
277 | + | |
278 | + .byte 0x0 /* end of children of main */ | |
279 | + | |
280 | + .byte 0x0 /* end of children of CU */ | |
281 | +debug_end: | |
282 | + | |
283 | + .section .debug_abbrev | |
284 | +.Ldebug_abbrev0: | |
285 | + | |
286 | + .uleb128 0x1 /* (abbrev code) */ | |
287 | + .uleb128 0x11 /* (TAG: DW_TAG_compile_unit) */ | |
288 | + .byte 0x1 /* DW_children_yes */ | |
289 | + .uleb128 0x25 /* (DW_AT_producer) */ | |
290 | + .uleb128 0x8 /* (DW_FORM_string) */ | |
291 | + .uleb128 0x13 /* (DW_AT_language) */ | |
292 | + .uleb128 0xb /* (DW_FORM_data1) */ | |
293 | + .uleb128 0x3 /* (DW_AT_name) */ | |
294 | + .uleb128 0x8 /* (DW_FORM_string) */ | |
295 | + .byte 0x0 | |
296 | + .byte 0x0 | |
297 | + | |
298 | + .uleb128 0x2 /* (abbrev code) */ | |
299 | + .uleb128 0x13 /* (TAG: DW_TAG_structure_type) */ | |
300 | + .byte 0x1 /* DW_children_yes */ | |
301 | + .uleb128 0x3 /* (DW_AT_name) */ | |
302 | + .uleb128 0x8 /* (DW_FORM_string) */ | |
303 | + .uleb128 0xb /* (DW_AT_byte_size) */ | |
304 | + .uleb128 0xb /* (DW_FORM_data1) */ | |
305 | + .byte 0 | |
306 | + .byte 0 | |
307 | + | |
308 | + .uleb128 0x3 /* (abbrev code) */ | |
309 | + .uleb128 0xd /* (TAG: DW_TAG_member) */ | |
310 | + .byte 0 /* DW_children_no */ | |
311 | + .uleb128 0x3 /* (DW_AT_name) */ | |
312 | + .uleb128 0x8 /* (DW_FORM_string) */ | |
313 | + .uleb128 0x49 /* (DW_AT_type) */ | |
314 | + .uleb128 0x13 /* (DW_FORM_ref4) */ | |
315 | + .uleb128 0x38 /* (DW_AT_data_member_location) */ | |
316 | + .uleb128 0xb /* (DW_FORM_data1) */ | |
317 | + .byte 0 | |
318 | + .byte 0 | |
319 | + | |
320 | + .uleb128 0x4 /* (abbrev code) */ | |
321 | + .uleb128 0x34 /* (TAG: DW_TAG_variable) */ | |
322 | + .byte 0x0 /* DW_children_yes */ | |
323 | + .uleb128 0x3 /* (DW_AT_name) */ | |
324 | + .uleb128 0x8 /* (DW_FORM_string) */ | |
325 | + .uleb128 0x02 /* (DW_AT_location) */ | |
326 | + .uleb128 0xa /* (DW_FORM_block1) */ | |
327 | + .uleb128 0x49 /* (DW_AT_type) */ | |
328 | + .uleb128 0x13 /* (DW_FORM_ref4) */ | |
329 | + .byte 0x0 | |
330 | + .byte 0x0 | |
331 | + | |
332 | + .uleb128 0x5 /* (abbrev code) */ | |
333 | + .uleb128 0xf /* (TAG: DW_TAG_pointer_type) */ | |
334 | + .byte 0x0 /* DW_children_no */ | |
335 | + .uleb128 0xb /* (DW_AT_byte_size) */ | |
336 | + .uleb128 0xb /* (DW_FORM_data1) */ | |
337 | + .uleb128 0x49 /* (DW_AT_type) */ | |
338 | + .uleb128 0x13 /* (DW_FORM_ref4) */ | |
339 | + .byte 0x0 | |
340 | + .byte 0x0 | |
341 | + | |
342 | + .uleb128 6 /* Abbrev code */ | |
343 | + .uleb128 0x2e /* DW_TAG_subprogram */ | |
344 | + .byte 1 /* has_children */ | |
345 | + .uleb128 0x3 /* DW_AT_name */ | |
346 | + .uleb128 0x8 /* DW_FORM_string */ | |
347 | + .uleb128 0x11 /* DW_AT_low_pc */ | |
348 | + .uleb128 0x1 /* DW_FORM_addr */ | |
349 | + .uleb128 0x12 /* DW_AT_high_pc */ | |
350 | + .uleb128 0x1 /* DW_FORM_addr */ | |
351 | + .uleb128 0x49 /* DW_AT_type */ | |
352 | + .uleb128 0x13 /* DW_FORM_ref4 */ | |
353 | + .uleb128 0x3f /* DW_AT_external */ | |
354 | + .uleb128 0xc /* DW_FORM_flag */ | |
355 | + .byte 0x0 /* Terminator */ | |
356 | + .byte 0x0 /* Terminator */ | |
357 | + | |
358 | + .uleb128 0x7 /* (abbrev code) */ | |
359 | + .uleb128 0x24 /* (TAG: DW_TAG_base_type) */ | |
360 | + .byte 0 /* DW_children_no */ | |
361 | + .uleb128 0xb /* (DW_AT_byte_size) */ | |
362 | + .uleb128 0xb /* (DW_FORM_data1) */ | |
363 | + .uleb128 0x3e /* (DW_AT_encoding) */ | |
364 | + .uleb128 0xb /* (DW_FORM_data1) */ | |
365 | + .uleb128 0x3 /* (DW_AT_name) */ | |
366 | + .uleb128 0x8 /* (DW_FORM_string) */ | |
367 | + .byte 0 | |
368 | + .byte 0 | |
369 | + | |
370 | + .byte 0x0 | |
371 | Index: gdb-7.3/gdb/testsuite/gdb.dwarf2/implptr-64bit.exp | |
372 | =================================================================== | |
373 | --- /dev/null 1970-01-01 00:00:00.000000000 +0000 | |
374 | +++ gdb-7.3/gdb/testsuite/gdb.dwarf2/implptr-64bit.exp 2011-09-26 22:38:52.000000000 +0200 | |
375 | @@ -0,0 +1,51 @@ | |
376 | +# Copyright 2011 Free Software Foundation, Inc. | |
377 | + | |
378 | +# This program is free software; you can redistribute it and/or modify | |
379 | +# it under the terms of the GNU General Public License as published by | |
380 | +# the Free Software Foundation; either version 3 of the License, or | |
381 | +# (at your option) any later version. | |
382 | +# | |
383 | +# This program is distributed in the hope that it will be useful, | |
384 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
385 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
386 | +# GNU General Public License for more details. | |
387 | +# | |
388 | +# You should have received a copy of the GNU General Public License | |
389 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
390 | +load_lib dwarf.exp | |
391 | + | |
392 | +# This test can only be run on targets which support DWARF-2 and use gas. | |
393 | +if {![dwarf2_support]} { | |
394 | + return 0 | |
395 | +} | |
396 | + | |
397 | +set testfile "implptr-64bit" | |
398 | +set srcfile ${testfile}.S | |
399 | +set mainfile main.c | |
400 | + | |
401 | +proc test { dwarf_version offset_size addr_size ref_addr_size } { | |
402 | + global testfile srcfile mainfile | |
403 | + | |
404 | + set opts {} | |
405 | + foreach n { dwarf_version offset_size addr_size ref_addr_size } { | |
406 | + lappend opts "additional_flags=-D[string toupper $n]=[expr "\$$n"]" | |
407 | + } | |
408 | + | |
409 | + set name "d${dwarf_version}o${offset_size}a${addr_size}r${ref_addr_size}" | |
410 | + set executable ${testfile}-${name} | |
411 | + if [prepare_for_testing ${testfile}.exp $executable "${srcfile} ${mainfile}" $opts] { | |
412 | + return -1 | |
413 | + } | |
414 | + | |
415 | + if ![runto_main] { | |
416 | + return -1 | |
417 | + } | |
418 | + | |
419 | + gdb_test "p/x p->f" " = 0x1010101" $name | |
420 | +} | |
421 | + | |
422 | +# DWARF_VERSION OFFSET_SIZE ADDR_SIZE REF_ADDR_SIZE | |
423 | +test 2 8 4 4 | |
424 | +test 2 4 8 8 | |
425 | +test 3 8 4 8 | |
426 | +test 3 4 8 4 |