Hello, I am investigating an issue we're seeing with GCC 4.7 where the compiler produces a DW_OP_GNU_deref_type like this: .byte 0x5 # DW_AT_GNU_call_site_value .byte 0x91 # DW_OP_fbreg .sleb128 0 .byte 0xf6 # DW_OP_GNU_deref_type .byte 0x4 .uleb128 0x25 This is what we get when GDB tries to print the parameter value's at entry: file_1.export_1 (param_1=99.0, param_1@entry=, str=...) at file_1.adb:3 I think I tracked the problem down, but I am unsure of where the problem should be fixed. So, here's what happens: GDB finds the DW_OP_GNU_deref_type operand, and starts evaluating it. This is in dwarf2expr.c: case DW_OP_GNU_deref_type: { [...] if (op == DW_OP_GNU_deref_type) { op_ptr = read_uleb128 (op_ptr, op_end, &type_die); type = dwarf_get_base_type (ctx, type_die, 0); } Here, read_uleb128 returns 0x25, as expected, and the associated die should be: .uleb128 0x2 # (DIE (0x25) DW_TAG_base_type) .byte 0x4 # DW_AT_byte_size .byte 0x4 # DW_AT_encoding .long .LASF3 # DW_AT_name: "FLOAT_32" However, dwarf_get_base_type fails to find it, and it's fairly easy to figure out why: dwarf_get_base_type just calls ctx->funcs->get_base_type, which is dwarf_expr_get_base_type. And the latter is merely a wrapper around dwarf2_get_die_type: > static struct type * > dwarf_expr_get_base_type (struct dwarf_expr_context *ctx, size_t die_offset) > { > struct dwarf_expr_baton *debaton = ctx->baton; > > return dwarf2_get_die_type (die_offset, debaton->per_cu); > } And dwarf2_get_die_type (through get_die_type_at_offset) try to locate the DIE by searching through the debug_types_type_hash by using that same offset (0x25). However, 0x25 is the offset within the unit, whereas the DIE was actually inserted using the absolute offset. So the lookup fails. First of all, I am a little surprised that an error like this would have slipped in, and I am really wondering whether I might be missing something. I looked at http://www.dwarfstd.org/doc/040408.1.html, to see if maybe the offset was supposed to be relocated, but it does not appear to be the case, the text is very explicit with the fact that the value should be an offset to the start of the CU. The fix seems relatively simple: Add the CU's offset to the deref's offset. But where should this be done? There are several places: (1) when calling dwarf_get_base_type (making dwarf_get_base_type require an absolute offset rather than a relative one) (2) Inside dwarf_get_base_type, when calling ctx->funcs->get_base_type; The description of that callback is unclear as to whether the offset is expected to be absolute or not (3) Inside dwarf_expr_get_base_type, when calling dwarf2_get_die_type (dwarf_expr_get_base_type is the ctx->funcs->get_base_type callback); (4) Inside dwarf2_get_die_type, when calling get_die_type_at_offset As unbelievable as option (4) might seem (this is an exported routine from dwarf2read.c), it almost seems like the correct one. The function's description reads: > /* Return the type of the DIE at DIE_OFFSET in the CU named by > PER_CU. */ > > struct type * > dwarf2_get_die_type (unsigned int die_offset, > struct dwarf2_per_cu_data *per_cu) It seems to me that DIE_OFFSET is expected to be a relative offset. I've audited the uses of that function, and it is used exclusively in dwarf2loc.c, either by dwarf_expr_get_base_type, or by disassemble_dwarf_expression, when disassembling various DW_OP_GNU_* operands, including our DW_OP_GNU_deref_type operand. And I also checked dwarf_expr_get_base_type, and it's only used to get the base type of the same DW_OP_GNU_* operands. I tested the change, and lo and behold, on x86_64-linux, I get the following fixes: * gdb.arch: +------------+------------+----------------------------------------------------+ | FAIL | PASS | amd64-entry-value.exp: entry: bt | | FAIL | PASS | amd64-entry-value.exp: entry: p j | | FAIL | PASS | amd64-entry-value.exp: entry: p j@entry | | FAIL | PASS | amd64-entry-value.exp: entry_stack: bt at entry | | FAIL | PASS | amd64-entry-value.exp: entry_stack: bt | | FAIL | PASS | amd64-entry-value.exp: entry_stack: p d9@entry | | FAIL | PASS | amd64-entry-value.exp: entry_stack: p da@entry | | FAIL | PASS | amd64-entry-value.exp: tailcall: bt | | FAIL | PASS | amd64-entry-value.exp: tailcall: p j | | FAIL | PASS | amd64-entry-value.exp: tailcall: p j@entry | +------------+------------+----------------------------------------------------+ (and it also fixes my problem). Thoughts? gdb/ChangeLog: * dwarf2read.c (dwarf2_get_die_type): Pass absolute offset in call to get_die_type_at_offset. Thanks, -- Joel