From 4bb744e410e0823b2f245c6c2059e88045c050fd Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Mon, 3 Dec 2012 21:09:12 +0100 Subject: [PATCH] Fix DW_OP_GNU_implicit_pointer offset bug (Tom Tromey). --- gdb-implicitpointer-offset.patch | 350 +++++++++++++++++++++++++++++++ gdb.spec | 9 +- 2 files changed, 358 insertions(+), 1 deletion(-) create mode 100644 gdb-implicitpointer-offset.patch diff --git a/gdb-implicitpointer-offset.patch b/gdb-implicitpointer-offset.patch new file mode 100644 index 0000000..067df12 --- /dev/null +++ b/gdb-implicitpointer-offset.patch @@ -0,0 +1,350 @@ +http://sourceware.org/ml/gdb-patches/2012-12/msg00030.html +Subject: Re: RFC: fix bug in DW_OP_GNU_implicit_pointer + +>>>>> "Jan" == Jan Kratochvil writes: + +Jan> And how it is implemented in GCC? + +Correctly. + +>> I updated the implptr-64bit test case to test the new code as well. + +Jan> This is .S test so GCC is not tested there. + +Yeah, I considered this, but I did not want to add a new test that would +be exposed to gcc version differences -- and testing gcc's output is +more properly done in the gcc test suite anyway. + +Jan> Maybe to call them now for example: +Jan> dwarf2_fetch_die_loc_cu_off +Jan> dwarf2_fetch_die_loc_sect_off + +Ok. + +Jan> Missing added TWO_CU here. + +Added. + +Tom + +2012-11-30 Tom Tromey + + * dwarf2read.c (dwarf2_fetch_die_loc_sect_off): New function. + (dwarf2_fetch_die_loc_cu_off): Rename from + dwarf2_fetch_die_location_block. Rewrite to use + dwarf2_fetch_die_loc_sect_off. + * dwarf2loc.h (dwarf2_fetch_die_loc_sect_off): Declare. + (dwarf2_fetch_die_loc_cu_off): Rename. + * dwarf2loc.c (indirect_pieced_value): Use + dwarf2_fetch_die_loc_sect_off. + * dwarf2expr.h (struct dwarf_expr_context) : Update + comment. + (struct dwarf_expr_piece) : Now a sect_offset. + * dwarf2expr.c (add_piece): Update. + (execute_stack_op) : Update comment. + +2012-11-30 Tom Tromey + + * gdb.dwarf2/implptr-64bit.exp: Run tests with two CUs as well. + (test): Add "two_cu" argument. + * gdb.dwarf2/implptr-64bit.S: Move subprogram later; use ref_addr + for types; allow two CUs. + +diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c +index 214b371..877add4 100644 +--- a/gdb/dwarf2expr.c ++++ b/gdb/dwarf2expr.c +@@ -342,7 +342,7 @@ add_piece (struct dwarf_expr_context *ctx, ULONGEST size, ULONGEST offset) + } + else if (p->location == DWARF_VALUE_IMPLICIT_POINTER) + { +- p->v.ptr.die.cu_off = ctx->len; ++ p->v.ptr.die.sect_off = ctx->len; + p->v.ptr.offset = value_as_long (dwarf_expr_fetch (ctx, 0)); + } + else if (p->location == DWARF_VALUE_REGISTER) +@@ -872,7 +872,7 @@ execute_stack_op (struct dwarf_expr_context *ctx, + error (_("DWARF-2 expression error: DW_OP_GNU_implicit_pointer " + "is not allowed in frame context")); + +- /* The referred-to DIE of cu_offset kind. */ ++ /* The referred-to DIE of sect_offset kind. */ + ctx->len = extract_unsigned_integer (op_ptr, ctx->ref_addr_size, + byte_order); + op_ptr += ctx->ref_addr_size; +diff --git a/gdb/dwarf2expr.h b/gdb/dwarf2expr.h +index 19efbfd..1b890dc 100644 +--- a/gdb/dwarf2expr.h ++++ b/gdb/dwarf2expr.h +@@ -165,7 +165,7 @@ struct dwarf_expr_context + + /* For DWARF_VALUE_LITERAL, the current literal value's length and + data. For DWARF_VALUE_IMPLICIT_POINTER, LEN is the offset of the +- target DIE of cu_offset kind. */ ++ target DIE of sect_offset kind. */ + ULONGEST len; + const gdb_byte *data; + +@@ -236,7 +236,7 @@ struct dwarf_expr_piece + struct + { + /* The referent DIE from DW_OP_GNU_implicit_pointer. */ +- cu_offset die; ++ sect_offset die; + /* The byte offset into the resulting data. */ + LONGEST offset; + } ptr; +diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c +index cadcc17..94a03ca 100644 +--- a/gdb/dwarf2loc.c ++++ b/gdb/dwarf2loc.c +@@ -425,8 +425,7 @@ per_cu_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset, + { + struct dwarf2_locexpr_baton block; + +- block = dwarf2_fetch_die_location_block (die_offset, per_cu, +- get_frame_pc, baton); ++ block = dwarf2_fetch_die_loc_cu_off (die_offset, per_cu, get_frame_pc, baton); + + /* DW_OP_call_ref is currently not supported. */ + gdb_assert (block.per_cu == per_cu); +@@ -2034,9 +2033,10 @@ indirect_pieced_value (struct value *value) + byte_offset = value_as_address (value); + + gdb_assert (piece); +- baton = dwarf2_fetch_die_location_block (piece->v.ptr.die, c->per_cu, +- get_frame_address_in_block_wrapper, +- frame); ++ baton ++ = dwarf2_fetch_die_loc_sect_off (piece->v.ptr.die, c->per_cu, ++ get_frame_address_in_block_wrapper, ++ frame); + + return dwarf2_evaluate_loc_desc_full (TYPE_TARGET_TYPE (type), frame, + baton.data, baton.size, baton.per_cu, +@@ -3201,8 +3201,8 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc, + op_ptr += size; + + offset.cu_off = uoffset; +- block = dwarf2_fetch_die_location_block (offset, per_cu, +- get_ax_pc, expr); ++ block = dwarf2_fetch_die_loc_cu_off (offset, per_cu, ++ get_ax_pc, expr); + + /* DW_OP_call_ref is currently not supported. */ + gdb_assert (block.per_cu == per_cu); +diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h +index 0f10767..6a8b3c8 100644 +--- a/gdb/dwarf2loc.h ++++ b/gdb/dwarf2loc.h +@@ -62,7 +62,12 @@ const gdb_byte *dwarf2_find_location_expression + size_t *locexpr_length, + CORE_ADDR pc); + +-struct dwarf2_locexpr_baton dwarf2_fetch_die_location_block ++struct dwarf2_locexpr_baton dwarf2_fetch_die_loc_sect_off ++ (sect_offset offset_in_cu, struct dwarf2_per_cu_data *per_cu, ++ CORE_ADDR (*get_frame_pc) (void *baton), ++ void *baton); ++ ++struct dwarf2_locexpr_baton dwarf2_fetch_die_loc_cu_off + (cu_offset offset_in_cu, struct dwarf2_per_cu_data *per_cu, + CORE_ADDR (*get_frame_pc) (void *baton), + void *baton); +diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c +index f4bd7a9..59dea05 100644 +--- a/gdb/dwarf2read.c ++++ b/gdb/dwarf2read.c +@@ -17343,12 +17343,11 @@ follow_die_ref (struct die_info *src_die, struct attribute *attr, + dwarf2_locexpr_baton->data has lifetime of PER_CU->OBJFILE. */ + + struct dwarf2_locexpr_baton +-dwarf2_fetch_die_location_block (cu_offset offset_in_cu, +- struct dwarf2_per_cu_data *per_cu, +- CORE_ADDR (*get_frame_pc) (void *baton), +- void *baton) ++dwarf2_fetch_die_loc_sect_off (sect_offset offset, ++ struct dwarf2_per_cu_data *per_cu, ++ CORE_ADDR (*get_frame_pc) (void *baton), ++ void *baton) + { +- sect_offset offset = { per_cu->offset.sect_off + offset_in_cu.cu_off }; + struct dwarf2_cu *cu; + struct die_info *die; + struct attribute *attr; +@@ -17403,6 +17402,20 @@ dwarf2_fetch_die_location_block (cu_offset offset_in_cu, + return retval; + } + ++/* Like dwarf2_fetch_die_loc_sect_off, but take a CU ++ offset. */ ++ ++struct dwarf2_locexpr_baton ++dwarf2_fetch_die_loc_cu_off (cu_offset offset_in_cu, ++ struct dwarf2_per_cu_data *per_cu, ++ CORE_ADDR (*get_frame_pc) (void *baton), ++ void *baton) ++{ ++ sect_offset offset = { per_cu->offset.sect_off + offset_in_cu.cu_off }; ++ ++ return dwarf2_fetch_die_loc_sect_off (offset, per_cu, get_frame_pc, baton); ++} ++ + /* Return the type of the DIE at DIE_OFFSET in the CU named by + PER_CU. */ + +diff --git a/gdb/testsuite/gdb.dwarf2/implptr-64bit.S b/gdb/testsuite/gdb.dwarf2/implptr-64bit.S +index be8db5c..d0d870a 100644 +--- a/gdb/testsuite/gdb.dwarf2/implptr-64bit.S ++++ b/gdb/testsuite/gdb.dwarf2/implptr-64bit.S +@@ -18,11 +18,12 @@ d: + /* Length of Compilation Unit Info */ + #if OFFSET_SIZE == 4 + # define OFFSET .4byte +- .4byte debug_end - 1f ++# define HEADER_LINE1 ++# define HEADER_LINE2(END) .4byte END - 1f + #elif OFFSET_SIZE == 8 + # define OFFSET .8byte +- .4byte 0xffffffff +- .8byte debug_end - 1f ++# define HEADER_LINE1 .4byte 0xffffffff ++# define HEADER_LINE2(END) .8byte END - 1f + #else + # error + #endif +@@ -40,6 +41,16 @@ d: + #else + # error + #endif ++ ++#if TWO_CU ++# define END1 .Lcu_end_1 ++#else ++# define END1 debug_end ++#endif ++ ++ HEADER_LINE1 ++ HEADER_LINE2(END1) ++ + 1: + .2byte DWARF_VERSION /* DWARF version number */ + OFFSET .Ldebug_abbrev0 /* Offset Into Abbrev. Section */ +@@ -68,13 +79,6 @@ d: + + .byte 0x0 /* end of children of DW_TAG_structure_type */ + +- .uleb128 6 /* Abbrev: DW_TAG_subprogram */ +- .ascii "main\0" /* DW_AT_name */ +- ADDR main /* DW_AT_low_pc */ +- ADDR main + 0x100 /* DW_AT_high_pc */ +- .4byte .Ltype_int - d /* DW_AT_type */ +- .byte 1 /* DW_AT_external */ +- + .Ltype_structptr: + .uleb128 0x5 /* DW_TAG_pointer_type */ + .byte ADDR_SIZE /* DW_AT_byte_size */ +@@ -90,7 +94,32 @@ d: + 3: + .byte 1, 1, 1, 1 + 2: +- .4byte .Ltype_struct - d /* DW_AT_type */ ++ REF_ADDR .Ltype_struct - d /* DW_AT_type */ ++ ++#if TWO_CU ++ .byte 0x0 /* end of children of CU */ ++.Lcu_end_1: ++ ++ HEADER_LINE1 ++ HEADER_LINE2 (debug_end) ++ ++1: ++ .2byte DWARF_VERSION /* DWARF version number */ ++ OFFSET .Ldebug_abbrev0 /* Offset Into Abbrev. Section */ ++ .byte ADDR_SIZE /* Pointer Size (in bytes) */ ++ ++ .uleb128 0x1 /* (DIE (0xb) DW_TAG_compile_unit) */ ++ .ascii "GNU C 4.4.3\0" /* DW_AT_producer */ ++ .byte 0x1 /* DW_AT_language */ ++ .ascii "1.c\0" /* DW_AT_name */ ++#endif ++ ++ .uleb128 6 /* Abbrev: DW_TAG_subprogram */ ++ .ascii "main\0" /* DW_AT_name */ ++ ADDR main /* DW_AT_low_pc */ ++ ADDR main + 0x100 /* DW_AT_high_pc */ ++ REF_ADDR .Ltype_int - d /* DW_AT_type */ ++ .byte 1 /* DW_AT_external */ + + .uleb128 0x4 /* (DW_TAG_variable) */ + .ascii "p\0" /* DW_AT_name */ +@@ -100,7 +129,7 @@ d: + REF_ADDR .Lvar_out - d /* referenced DIE */ + .sleb128 0 /* offset */ + 2: +- .4byte .Ltype_structptr - d /* DW_AT_type */ ++ REF_ADDR .Ltype_structptr - d /* DW_AT_type */ + + .byte 0x0 /* end of children of main */ + +@@ -152,7 +181,7 @@ debug_end: + .uleb128 0x02 /* (DW_AT_location) */ + .uleb128 0xa /* (DW_FORM_block1) */ + .uleb128 0x49 /* (DW_AT_type) */ +- .uleb128 0x13 /* (DW_FORM_ref4) */ ++ .uleb128 0x10 /* (DW_FORM_ref_addr) */ + .byte 0x0 + .byte 0x0 + +@@ -176,7 +205,7 @@ debug_end: + .uleb128 0x12 /* DW_AT_high_pc */ + .uleb128 0x1 /* DW_FORM_addr */ + .uleb128 0x49 /* DW_AT_type */ +- .uleb128 0x13 /* DW_FORM_ref4 */ ++ .uleb128 0x10 /* DW_FORM_ref_addr */ + .uleb128 0x3f /* DW_AT_external */ + .uleb128 0xc /* DW_FORM_flag */ + .byte 0x0 /* Terminator */ +diff --git a/gdb/testsuite/gdb.dwarf2/implptr-64bit.exp b/gdb/testsuite/gdb.dwarf2/implptr-64bit.exp +index 78f1594..066cf78 100644 +--- a/gdb/testsuite/gdb.dwarf2/implptr-64bit.exp ++++ b/gdb/testsuite/gdb.dwarf2/implptr-64bit.exp +@@ -22,16 +22,16 @@ if {![dwarf2_support]} { + standard_testfile .S + set mainfile main.c + +-proc test { dwarf_version offset_size addr_size ref_addr_size } { ++proc test { dwarf_version offset_size addr_size ref_addr_size two_cu } { + global testfile srcfile mainfile + + # 32-bit targets do not support any of the testcases; keep quiet there. + set opts {quiet} +- foreach n { dwarf_version offset_size addr_size ref_addr_size } { ++ foreach n { dwarf_version offset_size addr_size ref_addr_size two_cu } { + lappend opts "additional_flags=-D[string toupper $n]=[expr "\$$n"]" + } + +- set name "d${dwarf_version}o${offset_size}a${addr_size}r${ref_addr_size}" ++ set name "d${dwarf_version}o${offset_size}a${addr_size}r${ref_addr_size}t${two_cu}" + set executable ${testfile}-${name} + if [prepare_for_testing ${testfile}.exp $executable "${srcfile} ${mainfile}" $opts] { + return -1 +@@ -44,8 +44,12 @@ proc test { dwarf_version offset_size addr_size ref_addr_size } { + gdb_test "p/x p->f" " = 0x1010101" $name + } + +-# DWARF_VERSION OFFSET_SIZE ADDR_SIZE REF_ADDR_SIZE +-test 2 8 4 4 +-test 2 4 8 8 +-test 3 8 4 8 +-test 3 4 8 4 ++# DWARF_VERSION OFFSET_SIZE ADDR_SIZE REF_ADDR_SIZE TWO_CU ++test 2 8 4 4 0 ++test 2 4 8 8 0 ++test 3 8 4 8 0 ++test 3 4 8 4 0 ++test 2 8 4 4 1 ++test 2 4 8 8 1 ++test 3 8 4 8 1 ++test 3 4 8 4 1 + diff --git a/gdb.spec b/gdb.spec index d6d17cb..94d87d0 100644 --- a/gdb.spec +++ b/gdb.spec @@ -34,7 +34,7 @@ Version: 7.5.1 # The release always contains a leading reserved number, start it at 1. # `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing. -Release: 30%{?dist} +Release: 31%{?dist} License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and BSD and Public Domain Group: Development/Debuggers @@ -599,6 +599,9 @@ Patch816: gdb-rhbz795424-bitpos-25of25.patch Patch817: gdb-rhbz795424-bitpos-25of25-test.patch Patch818: gdb-rhbz795424-bitpos-lazyvalue.patch +# Fix DW_OP_GNU_implicit_pointer offset bug (Tom Tromey). +Patch819: gdb-implicitpointer-offset.patch + %if 0%{!?rhel:1} || 0%{?rhel} > 6 # RL_STATE_FEDORA_GDB would not be found for: # Patch642: gdb-readline62-ask-more-rh.patch @@ -936,6 +939,7 @@ find -name "*.info*"|xargs rm -f %patch816 -p1 %patch817 -p1 %patch818 -p1 +%patch819 -p1 %patch393 -p1 %if 0%{!?el5:1} || 0%{?scl:1} @@ -1434,6 +1438,9 @@ fi %endif # 0%{!?el5:1} || "%{_target_cpu}" == "noarch" %changelog +* Mon Dec 3 2012 Jan Kratochvil - 7.5.1-31.fc18 +- Fix DW_OP_GNU_implicit_pointer offset bug (Tom Tromey). + * Sun Dec 2 2012 Jan Kratochvil - 7.5.1-30.fc18 - Temporarily disable PDF in gdb-doc before texinfo RH BZ 876710 gets fixed.