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
6 on 64-bit targets DWARF-3+ is used DW_OP_GNU_implicit_pointer does not work.
9 This type of reference (DW_FORM_ref_addr) is the size of an address on
10 the target architecture;
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).
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
24 GDB currently parsed DW_OP_GNU_implicit_pointer the DWARF-2 way, being
25 incompatible with DWARF-3+.
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).
31 No regressions on {x86_64,x86_64-m32,i686}-fedora16pre-linux-gnu.
39 2011-09-26 Jan Kratochvil <jan.kratochvil@redhat.com>
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.
53 2011-09-26 Jan Kratochvil <jan.kratochvil@redhat.com>
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.
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
65 ctx->gdbarch = get_frame_arch (this_frame);
66 ctx->addr_size = addr_size;
67 + ctx->ref_addr_size = -1;
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
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"));
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,
87 - op_ptr += ctx->addr_size;
88 + op_ptr += ctx->ref_addr_size;
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. */
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. */
104 /* Offset used to relocate DW_OP_addr argument. */
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 *
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);
118 ctx->read_reg = dwarf_expr_read_reg;
119 @@ -1507,6 +1508,7 @@ dwarf2_loc_desc_needs_frame (const gdb_b
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);
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);
135 +/* Return the DW_FORM_ref_addr size given in the compilation unit header for
137 +int dwarf2_per_cu_ref_addr_size (struct dwarf2_per_cu_data *cu);
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);
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;
150 +/* See its dwarf2loc.h declaration. */
153 +dwarf2_per_cu_ref_addr_size (struct dwarf2_per_cu_data *per_cu)
155 + struct comp_unit_head cu_header_local;
156 + const struct comp_unit_head *cu_headerp;
158 + cu_headerp = per_cu_header_read_in (&cu_header_local, per_cu);
160 + if (cu_headerp->version == 2)
161 + return cu_headerp->addr_size;
163 + return cu_headerp->offset_size;
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
174 +/* Copyright 2010, 2011 Free Software Foundation, Inc.
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.
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.
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/>. */
189 + .section .debug_info
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
198 + .8byte debug_end - 1f
203 +# define ADDR .4byte
204 +#elif ADDR_SIZE == 8
205 +# define ADDR .8byte
209 +#if REF_ADDR_SIZE == 4
210 +# define REF_ADDR .4byte
211 +#elif REF_ADDR_SIZE == 8
212 +# define REF_ADDR .8byte
217 + .2byte DWARF_VERSION /* DWARF version number */
218 + OFFSET .Ldebug_abbrev0 /* Offset Into Abbrev. Section */
219 + .byte ADDR_SIZE /* Pointer Size (in bytes) */
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 */
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 */
233 + .uleb128 0x2 /* DW_TAG_structure_type */
234 + .ascii "s\0" /* DW_AT_name */
235 + .byte 4 /* DW_AT_byte_size */
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 */
242 + .byte 0x0 /* end of children of DW_TAG_structure_type */
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 */
252 + .uleb128 0x5 /* DW_TAG_pointer_type */
253 + .byte ADDR_SIZE /* DW_AT_byte_size */
254 + .4byte .Ltype_struct - d /* DW_AT_type */
257 + .uleb128 0x4 /* (DW_TAG_variable) */
258 + .ascii "v\0" /* DW_AT_name */
259 + .byte 2f - 1f /* DW_AT_location: DW_FORM_block1 */
261 + .byte 0x9e /* DW_OP_implicit_value */
266 + .4byte .Ltype_struct - d /* DW_AT_type */
268 + .uleb128 0x4 /* (DW_TAG_variable) */
269 + .ascii "p\0" /* DW_AT_name */
270 + .byte 2f - 1f /* DW_AT_location: DW_FORM_block1 */
272 + .byte 0xf2 /* DW_OP_GNU_implicit_pointer */
273 + REF_ADDR .Lvar_out - d /* referenced DIE */
274 + .sleb128 0 /* offset */
276 + .4byte .Ltype_structptr - d /* DW_AT_type */
278 + .byte 0x0 /* end of children of main */
280 + .byte 0x0 /* end of children of CU */
283 + .section .debug_abbrev
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) */
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) */
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) */
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) */
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) */
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 */
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) */
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
376 +# Copyright 2011 Free Software Foundation, Inc.
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.
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.
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/>.
392 +# This test can only be run on targets which support DWARF-2 and use gas.
393 +if {![dwarf2_support]} {
397 +set testfile "implptr-64bit"
398 +set srcfile ${testfile}.S
401 +proc test { dwarf_version offset_size addr_size ref_addr_size } {
402 + global testfile srcfile mainfile
405 + foreach n { dwarf_version offset_size addr_size ref_addr_size } {
406 + lappend opts "additional_flags=-D[string toupper $n]=[expr "\$$n"]"
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] {
419 + gdb_test "p/x p->f" " = 0x1010101" $name
422 +# DWARF_VERSION OFFSET_SIZE ADDR_SIZE REF_ADDR_SIZE