[gdb/f16] [vla] Fix VLA arrays displayed in `bt full' (BZ 738482). Fix DW_OP_GNU_implicit_pointer for DWARF32

Jan Kratochvil jankratochvil at fedoraproject.org
Mon Sep 26 21:13:32 UTC 2011


commit 7649e489fb87d30b50d6e0c000ef96afc9e61fcf
Author: Jan Kratochvil <jan.kratochvil at redhat.com>
Date:   Mon Sep 26 23:13:14 2011 +0200

    [vla] Fix VLA arrays displayed in `bt full' (BZ 738482).
    Fix DW_OP_GNU_implicit_pointer for DWARF32 v3+ on 64-bit arches.
    Fix internal error on some optimized-out values.

 gdb-implptr-64bit-1of2.patch           |  110 +++++++++
 gdb-implptr-64bit-2of2.patch           |  411 ++++++++++++++++++++++++++++++++
 gdb-optimized-out-internal-error.patch |  302 +++++++++++++++++++++++
 gdb-vla-frame-set.patch                |   91 +++++++
 gdb.spec                               |   21 ++-
 5 files changed, 934 insertions(+), 1 deletions(-)
---
diff --git a/gdb-implptr-64bit-1of2.patch b/gdb-implptr-64bit-1of2.patch
new file mode 100644
index 0000000..e24595d
--- /dev/null
+++ b/gdb-implptr-64bit-1of2.patch
@@ -0,0 +1,110 @@
+http://sourceware.org/ml/gdb-patches/2011-09/msg00450.html
+Subject: [patch 1/2] Code cleanup: Unify dwarf2_per_cu_addr_size, dwarf2_per_cu_offset_size
+
+Hi,
+
+this is more rather for patch 2/2, it has positive LoC change but still
+I would find it applicable even on its own.
+
+No functionality change intended.
+
+
+Thanks,
+Jan
+
+
+gdb/
+2011-09-26  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
+	Code cleanup.
+	* dwarf2read.c (per_cu_header_read_in): New function.
+	(dwarf2_per_cu_addr_size, dwarf2_per_cu_offset_size): Use it, with new
+	variables cu_header_local and cu_headerp.
+
+--- a/gdb/dwarf2read.c
++++ b/gdb/dwarf2read.c
+@@ -15187,26 +15187,42 @@ dwarf2_per_cu_objfile (struct dwarf2_per_cu_data *per_cu)
+   return objfile;
+ }
+ 
++/* Return comp_unit_head for PER_CU, either already available in PER_CU->CU
++   (CU_HEADERP is unused in such case) or prepare a temporary copy at
++   CU_HEADERP first.  */
++
++static const struct comp_unit_head *
++per_cu_header_read_in (struct comp_unit_head *cu_headerp,
++		       struct dwarf2_per_cu_data *per_cu)
++{
++  struct objfile *objfile;
++  struct dwarf2_per_objfile *per_objfile;
++  gdb_byte *info_ptr;
++
++  if (per_cu->cu)
++    return &per_cu->cu->header;
++
++  objfile = per_cu->objfile;
++  per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
++  info_ptr = per_objfile->info.buffer + per_cu->offset;
++
++  memset (cu_headerp, 0, sizeof (*cu_headerp));
++  read_comp_unit_head (cu_headerp, info_ptr, objfile->obfd);
++
++  return cu_headerp;
++}
++
+ /* Return the address size given in the compilation unit header for CU.  */
+ 
+ CORE_ADDR
+ dwarf2_per_cu_addr_size (struct dwarf2_per_cu_data *per_cu)
+ {
+-  if (per_cu->cu)
+-    return per_cu->cu->header.addr_size;
+-  else
+-    {
+-      /* If the CU is not currently read in, we re-read its header.  */
+-      struct objfile *objfile = per_cu->objfile;
+-      struct dwarf2_per_objfile *per_objfile
+-	= objfile_data (objfile, dwarf2_objfile_data_key);
+-      gdb_byte *info_ptr = per_objfile->info.buffer + per_cu->offset;
+-      struct comp_unit_head cu_header;
++  struct comp_unit_head cu_header_local;
++  const struct comp_unit_head *cu_headerp;
+ 
+-      memset (&cu_header, 0, sizeof cu_header);
+-      read_comp_unit_head (&cu_header, info_ptr, objfile->obfd);
+-      return cu_header.addr_size;
+-    }
++  cu_headerp = per_cu_header_read_in (&cu_header_local, per_cu);
++
++  return cu_headerp->addr_size;
+ }
+ 
+ /* Return the offset size given in the compilation unit header for CU.  */
+@@ -15214,21 +15230,12 @@ dwarf2_per_cu_addr_size (struct dwarf2_per_cu_data *per_cu)
+ int
+ dwarf2_per_cu_offset_size (struct dwarf2_per_cu_data *per_cu)
+ {
+-  if (per_cu->cu)
+-    return per_cu->cu->header.offset_size;
+-  else
+-    {
+-      /* If the CU is not currently read in, we re-read its header.  */
+-      struct objfile *objfile = per_cu->objfile;
+-      struct dwarf2_per_objfile *per_objfile
+-	= objfile_data (objfile, dwarf2_objfile_data_key);
+-      gdb_byte *info_ptr = per_objfile->info.buffer + per_cu->offset;
+-      struct comp_unit_head cu_header;
++  struct comp_unit_head cu_header_local;
++  const struct comp_unit_head *cu_headerp;
+ 
+-      memset (&cu_header, 0, sizeof cu_header);
+-      read_comp_unit_head (&cu_header, info_ptr, objfile->obfd);
+-      return cu_header.offset_size;
+-    }
++  cu_headerp = per_cu_header_read_in (&cu_header_local, per_cu);
++
++  return cu_headerp->offset_size;
+ }
+ 
+ /* Return the text offset of the CU.  The returned offset comes from
+
diff --git a/gdb-implptr-64bit-2of2.patch b/gdb-implptr-64bit-2of2.patch
new file mode 100644
index 0000000..d180674
--- /dev/null
+++ b/gdb-implptr-64bit-2of2.patch
@@ -0,0 +1,411 @@
+http://sourceware.org/ml/gdb-patches/2011-09/msg00451.html
+Subject: [patch 2/2] Fix DW_OP_GNU_implicit_pointer for DWARF32 v3+ on 64-bit arches
+
+Hi,
+
+on 64-bit targets DWARF-3+ is used DW_OP_GNU_implicit_pointer does not work.
+
+DWARF-2 says:
+	This type of reference (DW_FORM_ref_addr) is the size of an address on
+	the target architecture; 
+DWARF-3 says:
+	1.5.1 Upward Compatibility
+	References that use the attribute form DW_FORM_ref_addr are specified
+	to be four bytes in the DWARF 32-bit format and eight bytes in the
+	DWARF 64-bit format, while DWARF Version 2 specifies that such
+	references have the same size as an address on the target system (see
+	Sections 7.4 and 7.5.4).
+
+	(DW_FORM_ref_addr)
+	In the 32-bit DWARF format, this offset is a 4-byte unsigned value; in
+	the 64-bit DWARF format, it is an 8-byte unsigned value (see Section
+	7.4).
+
+GDB currently parsed DW_OP_GNU_implicit_pointer the DWARF-2 way, being
+incompatible with DWARF-3+.
+
+I think DW_OP_GNU_implicit_pointer does not make sense to be used from
+.debug_frame (DWARF-5 is not yet released to say more) so for .debug_frame its
+use is just not permitted (the code would be more complicated otherwise).
+
+No regressions on {x86_64,x86_64-m32,i686}-fedora16pre-linux-gnu.
+
+
+Thanks,
+Jan
+
+
+gdb/
+2011-09-26  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
+	Fix DW_OP_GNU_implicit_pointer for DWARF32 v3+ on 64-bit arches.
+	* dwarf2-frame.c (execute_stack_op): Initialize ctx->ref_addr_size.
+	* dwarf2expr.c (execute_stack_op) <DW_OP_GNU_implicit_pointer>: Use
+	ctx->ref_addr_size.  Handle its invalid value.
+	* dwarf2expr.h (struct dwarf_expr_context): New field ref_addr_size.
+	* dwarf2loc.c (dwarf2_evaluate_loc_desc_full)
+	(dwarf2_loc_desc_needs_frame): Initialize ctx->ref_addr_size.
+	* dwarf2loc.h (dwarf2_per_cu_ref_addr_size): New declaration.
+	* dwarf2read.c (decode_locdesc): Initialize ctx->ref_addr_size.
+	(dwarf2_per_cu_ref_addr_size): New function.
+
+gdb/testsuite/
+2011-09-26  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
+	Fix DW_OP_GNU_implicit_pointer for DWARF32 v3+ on 64-bit arches.
+	* gdb.dwarf2/implptr-64bit.S: New file.
+	* gdb.dwarf2/implptr-64bit.exp: New file.
+
+--- a/gdb/dwarf2-frame.c
++++ b/gdb/dwarf2-frame.c
+@@ -371,6 +371,7 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size,
+ 
+   ctx->gdbarch = get_frame_arch (this_frame);
+   ctx->addr_size = addr_size;
++  ctx->ref_addr_size = -1;
+   ctx->offset = offset;
+   ctx->baton = this_frame;
+   ctx->funcs = &dwarf2_frame_ctx_funcs;
+--- a/gdb/dwarf2expr.c
++++ b/gdb/dwarf2expr.c
+@@ -709,10 +709,14 @@ execute_stack_op (struct dwarf_expr_context *ctx,
+ 	    ULONGEST die;
+ 	    LONGEST len;
+ 
++	    if (ctx->ref_addr_size == -1)
++	      error (_("DWARF-2 expression error: DW_OP_GNU_implicit_pointer "
++		       "is not allowed in frame context"));
++
+ 	    /* The referred-to DIE.  */
+-	    ctx->len = extract_unsigned_integer (op_ptr, ctx->addr_size,
++	    ctx->len = extract_unsigned_integer (op_ptr, ctx->ref_addr_size,
+ 						 byte_order);
+-	    op_ptr += ctx->addr_size;
++	    op_ptr += ctx->ref_addr_size;
+ 
+ 	    /* The byte offset into the data.  */
+ 	    op_ptr = read_sleb128 (op_ptr, op_end, &len);
+--- a/gdb/dwarf2expr.h
++++ b/gdb/dwarf2expr.h
+@@ -125,6 +125,10 @@ struct dwarf_expr_context
+   /* Target address size in bytes.  */
+   int addr_size;
+ 
++  /* DW_FORM_ref_addr size in bytes.  If -1 DWARF is executed from a frame
++     context and operations depending on DW_FORM_ref_addr are not allowed.  */
++  int ref_addr_size;
++
+   /* Offset used to relocate DW_OP_addr argument.  */
+   CORE_ADDR offset;
+ 
+--- a/gdb/dwarf2loc.c
++++ b/gdb/dwarf2loc.c
+@@ -1118,6 +1118,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
+ 
+   ctx->gdbarch = get_objfile_arch (objfile);
+   ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
++  ctx->ref_addr_size = dwarf2_per_cu_ref_addr_size (per_cu);
+   ctx->offset = dwarf2_per_cu_text_offset (per_cu);
+   ctx->baton = &baton;
+   ctx->funcs = &dwarf_expr_ctx_funcs;
+@@ -1398,6 +1399,7 @@ dwarf2_loc_desc_needs_frame (const gdb_byte *data, unsigned short size,
+ 
+   ctx->gdbarch = get_objfile_arch (objfile);
+   ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
++  ctx->ref_addr_size = dwarf2_per_cu_ref_addr_size (per_cu);
+   ctx->offset = dwarf2_per_cu_text_offset (per_cu);
+   ctx->baton = &baton;
+   ctx->funcs = &needs_frame_ctx_funcs;
+--- a/gdb/dwarf2loc.h
++++ b/gdb/dwarf2loc.h
+@@ -39,6 +39,10 @@ struct objfile *dwarf2_per_cu_objfile (struct dwarf2_per_cu_data *cu);
+ /* Return the address size given in the compilation unit header for CU.  */
+ CORE_ADDR dwarf2_per_cu_addr_size (struct dwarf2_per_cu_data *cu);
+ 
++/* Return the DW_FORM_ref_addr size given in the compilation unit header for
++   CU.  */
++int dwarf2_per_cu_ref_addr_size (struct dwarf2_per_cu_data *cu);
++
+ /* Return the offset size given in the compilation unit header for CU.  */
+ int dwarf2_per_cu_offset_size (struct dwarf2_per_cu_data *cu);
+ 
+--- a/gdb/dwarf2read.c
++++ b/gdb/dwarf2read.c
+@@ -15238,6 +15239,22 @@ dwarf2_per_cu_offset_size (struct dwarf2_per_cu_data *per_cu)
+   return cu_headerp->offset_size;
+ }
+ 
++/* See its dwarf2loc.h declaration.  */
++
++int
++dwarf2_per_cu_ref_addr_size (struct dwarf2_per_cu_data *per_cu)
++{
++  struct comp_unit_head cu_header_local;
++  const struct comp_unit_head *cu_headerp;
++
++  cu_headerp = per_cu_header_read_in (&cu_header_local, per_cu);
++
++  if (cu_headerp->version == 2)
++    return cu_headerp->addr_size;
++  else
++    return cu_headerp->offset_size;
++}
++
+ /* Return the text offset of the CU.  The returned offset comes from
+    this CU's objfile.  If this objfile came from a separate debuginfo
+    file, then the offset may be different from the corresponding
+--- /dev/null
++++ b/gdb/testsuite/gdb.dwarf2/implptr-64bit.S
+@@ -0,0 +1,197 @@
++/* Copyright 2010, 2011 Free Software Foundation, Inc.
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 3 of the License, or
++   (at your option) any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
++
++	.section	.debug_info
++d:
++	/* Length of Compilation Unit Info */
++#if OFFSET_SIZE == 4
++# define OFFSET .4byte
++	.4byte	debug_end - 1f
++#elif OFFSET_SIZE == 8
++# define OFFSET .8byte
++	.4byte	0xffffffff
++	.8byte	debug_end - 1f
++#else
++# error
++#endif
++#if ADDR_SIZE == 4
++# define ADDR .4byte
++#elif ADDR_SIZE == 8
++# define ADDR .8byte
++#else
++# error
++#endif
++#if REF_ADDR_SIZE == 4
++# define REF_ADDR .4byte
++#elif REF_ADDR_SIZE == 8
++# define REF_ADDR .8byte
++#else
++# error
++#endif
++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 */
++
++.Ltype_int:
++	.uleb128 0x7	/* DW_TAG_base_type */
++	.byte	0x4	/* DW_AT_byte_size */
++	.byte	0x5	/* DW_AT_encoding */
++	.ascii "int\0"	/* DW_AT_name */
++
++.Ltype_struct:
++	.uleb128 0x2	/* DW_TAG_structure_type */
++	.ascii "s\0"	/* DW_AT_name */
++	.byte	4	/* DW_AT_byte_size */
++
++	.uleb128 0x3	/* DW_TAG_member */
++	.ascii "f\0"	/* DW_AT_name */
++	.4byte	.Ltype_int - d	/* DW_AT_type */
++	.byte	0	/* DW_AT_data_member_location */
++
++	.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 */
++	.4byte	.Ltype_struct - d	/* DW_AT_type */
++
++.Lvar_out:
++	.uleb128 0x4	/* (DW_TAG_variable) */
++	.ascii "v\0"	/* DW_AT_name */
++	.byte	2f - 1f	/* DW_AT_location: DW_FORM_block1 */
++1:
++	.byte	0x9e	/* DW_OP_implicit_value */
++	.uleb128  2f - 3f
++3:
++	.byte	1, 1, 1, 1
++2:
++	.4byte	.Ltype_struct - d	/* DW_AT_type */
++
++	.uleb128 0x4	/* (DW_TAG_variable) */
++	.ascii "p\0"	/* DW_AT_name */
++	.byte	2f - 1f	/* DW_AT_location: DW_FORM_block1 */
++1:
++	.byte	0xf2	/* DW_OP_GNU_implicit_pointer */
++	REF_ADDR	.Lvar_out - d	/* referenced DIE */
++	.sleb128	0	/* offset */
++2:
++	.4byte	.Ltype_structptr - d	/* DW_AT_type */
++
++	.byte	0x0	/* end of children of main */
++
++	.byte	0x0	/* end of children of CU */
++debug_end:
++
++	.section	.debug_abbrev
++.Ldebug_abbrev0:
++
++	.uleb128 0x1	/* (abbrev code) */
++	.uleb128 0x11	/* (TAG: DW_TAG_compile_unit) */
++	.byte	0x1	/* DW_children_yes */
++	.uleb128 0x25	/* (DW_AT_producer) */
++	.uleb128 0x8	/* (DW_FORM_string) */
++	.uleb128 0x13	/* (DW_AT_language) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.uleb128 0x3	/* (DW_AT_name) */
++	.uleb128 0x8	/* (DW_FORM_string) */
++	.byte	0x0
++	.byte	0x0
++
++	.uleb128 0x2	/* (abbrev code) */
++	.uleb128 0x13	/* (TAG: DW_TAG_structure_type) */
++	.byte	0x1	/* DW_children_yes */
++	.uleb128 0x3	/* (DW_AT_name) */
++	.uleb128 0x8	/* (DW_FORM_string) */
++	.uleb128 0xb	/* (DW_AT_byte_size) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.byte	0
++	.byte	0
++
++	.uleb128 0x3	/* (abbrev code) */
++	.uleb128 0xd	/* (TAG: DW_TAG_member) */
++	.byte	0	/* DW_children_no */
++	.uleb128 0x3	/* (DW_AT_name) */
++	.uleb128 0x8	/* (DW_FORM_string) */
++	.uleb128 0x49	/* (DW_AT_type) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.uleb128 0x38	/* (DW_AT_data_member_location) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.byte	0
++	.byte	0
++
++	.uleb128 0x4	/* (abbrev code) */
++	.uleb128 0x34	/* (TAG: DW_TAG_variable) */
++	.byte	0x0	/* DW_children_yes */
++	.uleb128 0x3	/* (DW_AT_name) */
++	.uleb128 0x8	/* (DW_FORM_string) */
++	.uleb128 0x02	/* (DW_AT_location) */
++	.uleb128 0xa	/* (DW_FORM_block1) */
++	.uleb128 0x49	/* (DW_AT_type) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.byte	0x0
++	.byte	0x0
++
++	.uleb128 0x5	/* (abbrev code) */
++	.uleb128 0xf	/* (TAG: DW_TAG_pointer_type) */
++	.byte	0x0	/* DW_children_no */
++	.uleb128 0xb	/* (DW_AT_byte_size) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.uleb128 0x49	/* (DW_AT_type) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.byte	0x0
++	.byte	0x0
++
++	.uleb128	6			/* Abbrev code */
++	.uleb128	0x2e			/* DW_TAG_subprogram */
++	.byte		1			/* has_children */
++	.uleb128	0x3			/* DW_AT_name */
++	.uleb128	0x8			/* DW_FORM_string */
++	.uleb128	0x11			/* DW_AT_low_pc */
++	.uleb128	0x1			/* DW_FORM_addr */
++	.uleb128	0x12			/* DW_AT_high_pc */
++	.uleb128	0x1			/* DW_FORM_addr */
++	.uleb128	0x49			/* DW_AT_type */
++	.uleb128	0x13			/* DW_FORM_ref4 */
++	.uleb128	0x3f			/* DW_AT_external */
++	.uleb128	0xc			/* DW_FORM_flag */
++	.byte		0x0			/* Terminator */
++	.byte		0x0			/* Terminator */
++
++	.uleb128 0x7	/* (abbrev code) */
++	.uleb128 0x24	/* (TAG: DW_TAG_base_type) */
++	.byte	0	/* DW_children_no */
++	.uleb128 0xb	/* (DW_AT_byte_size) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.uleb128 0x3e	/* (DW_AT_encoding) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.uleb128 0x3	/* (DW_AT_name) */
++	.uleb128 0x8	/* (DW_FORM_string) */
++	.byte	0
++	.byte	0
++
++	.byte	0x0
+--- /dev/null
++++ b/gdb/testsuite/gdb.dwarf2/implptr-64bit.exp
+@@ -0,0 +1,51 @@
++# Copyright 2011 Free Software Foundation, Inc.
++
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program.  If not, see <http://www.gnu.org/licenses/>.
++load_lib dwarf.exp
++
++# This test can only be run on targets which support DWARF-2 and use gas.
++if {![dwarf2_support]} {
++    return 0  
++}
++
++set testfile "implptr-64bit"
++set srcfile ${testfile}.S
++set mainfile main.c
++
++proc test { dwarf_version offset_size addr_size ref_addr_size } {
++    global testfile srcfile mainfile
++
++    set opts {}
++    foreach n { dwarf_version offset_size addr_size ref_addr_size } {
++	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 executable ${testfile}-${name}
++    if [prepare_for_testing ${testfile}.exp $executable "${srcfile} ${mainfile}" $opts] {
++	return -1
++    }
++
++    if ![runto_main] {
++	return -1
++    }
++
++    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
+
diff --git a/gdb-optimized-out-internal-error.patch b/gdb-optimized-out-internal-error.patch
new file mode 100644
index 0000000..1588ce6
--- /dev/null
+++ b/gdb-optimized-out-internal-error.patch
@@ -0,0 +1,302 @@
+http://sourceware.org/ml/gdb-patches/2011-09/msg00449.html
+Subject: [patch] Fix internal error on optimized-out values (regression by me)
+
+Hi,
+
+since:
+	Re: [patch] Code cleanup: Introduce allocate_optimized_out_value
+	http://sourceware.org/ml/gdb-patches/2011-07/msg00327.html
+	acfe85f56075910a3ba5e8b76189e0770079b8d1
+can occur:
+	(gdb) p p->f
+	valops.c:1118: internal-error: Unexpected lazy value type.
+	A problem internal to GDB has been detected,
+
+in that mail referenced above:
+# It is true it would be definitely a bug in a code incompatible with such
+# change so one may rather fix that possible regression there.
+
+so this testcase exploits such case.  The problem is formerly the code
+allocated (in some cases) optimized out values as non-lazy ones.  Now they are
+allocated all as lazy (*) which breaks some code not expecting lazy values.
+
+(*) Such lazy optimized out value still gets silently allocate_value_contents
+    by value_fetch_lazy, allocate_value_contents should be suppressed in such
+    case; such more radical change has never been made.
+
+Formerly (incl. gdb-7.3) did:
+	(gdb) p p->f
+	$1 = 0
+which was also wrong, ((struct *) <optimized out>)->field should be IMO still
+<optimized out>; just it became internal-error now.
+
+GDB usually does require_not_optimized_out throwing error() when it meets any
+first <optimized out> value.  I have just produced new optimized value
+instead; require_not_optimized_out is not exported and I find it better this
+way.
+
+Following the rule that it is better if GDB does something wrong rather then
+it throws internal-error to make the patch from July above fully safe one
+would have to change allocate_optimized_out_value to allocate everything as
+non-lazy.  I find that as a too ugly workaround of the codebase.
+
+No regressions on {x86_64,x86_64-m32,i686}-fedora16pre-linux-gnu.
+
+
+Andre, do you still see the bug even with this patch?
+
+
+Thanks,
+Jan
+
+
+gdb/
+2011-09-26  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
+	Fix internal error regression.
+	* value.c (value_primitive_field): Handle value_optimized_out.  Move
+	packed bitfields comment.
+
+gdb/testsuite/
+2011-09-26  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
+	Fix internal error regression.
+	* gdb.dwarf2/implptr-optimized-out.S: New file.
+	* gdb.dwarf2/implptr-optimized-out.exp: New file.
+
+--- a/gdb/value.c
++++ b/gdb/value.c
+@@ -2482,16 +2482,19 @@ value_primitive_field (struct value *arg1, int offset,
+      description correctly.  */
+   check_typedef (type);
+ 
+-  /* Handle packed fields */
+-
+-  if (TYPE_FIELD_BITSIZE (arg_type, fieldno))
++  if (value_optimized_out (arg1))
++    v = allocate_optimized_out_value (type);
++  else if (TYPE_FIELD_BITSIZE (arg_type, fieldno))
+     {
+-      /* Create a new value for the bitfield, with bitpos and bitsize
++      /* Handle packed fields.
++
++	 Create a new value for the bitfield, with bitpos and bitsize
+ 	 set.  If possible, arrange offset and bitpos so that we can
+ 	 do a single aligned read of the size of the containing type.
+ 	 Otherwise, adjust offset to the byte containing the first
+ 	 bit.  Assume that the address, offset, and embedded offset
+ 	 are sufficiently aligned.  */
++
+       int bitpos = TYPE_FIELD_BITPOS (arg_type, fieldno);
+       int container_bitsize = TYPE_LENGTH (type) * 8;
+ 
+--- /dev/null
++++ b/gdb/testsuite/gdb.dwarf2/implptr-optimized-out.S
+@@ -0,0 +1,166 @@
++/* Copyright 2010, 2011 Free Software Foundation, Inc.
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 3 of the License, or
++   (at your option) any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
++
++	.section	.debug_info
++d:
++	.long	debug_end - 1f	/* Length of Compilation Unit Info */
++1:
++	.2byte	0x3	/* DWARF version number */
++	.long	.Ldebug_abbrev0	/* Offset Into Abbrev. Section */
++	.byte	0x4	/* 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 */
++
++.Ltype_int:
++	.uleb128 0x7	/* DW_TAG_base_type */
++	.byte	0x4	/* DW_AT_byte_size */
++	.byte	0x5	/* DW_AT_encoding */
++	.ascii "int\0"	/* DW_AT_name */
++
++.Ltype_struct:
++	.uleb128 0x2	/* DW_TAG_structure_type */
++	.ascii "s\0"	/* DW_AT_name */
++	.byte	4	/* DW_AT_byte_size */
++
++	.uleb128 0x3	/* DW_TAG_member */
++	.ascii "f\0"	/* DW_AT_name */
++	.4byte	.Ltype_int - d	/* DW_AT_type */
++	.byte	0	/* DW_AT_data_member_location */
++
++	.byte	0x0	/* end of children of DW_TAG_structure_type */
++
++	.uleb128	6			/* Abbrev: DW_TAG_subprogram */
++	.ascii		"main\0"		/* DW_AT_name */
++	.4byte		main			/* DW_AT_low_pc */
++	.4byte		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	0x4	/* DW_AT_byte_size */
++	.long	.Ltype_struct - d	/* DW_AT_type */
++
++.Lvar_out:
++	.uleb128 0x4	/* (DW_TAG_variable) */
++	.ascii "v\0"	/* DW_AT_name */
++	.byte	0	/* DW_AT_location: DW_FORM_block1 */
++	.4byte	.Ltype_struct - d	/* DW_AT_type */
++
++	.uleb128 0x4	/* (DW_TAG_variable) */
++	.ascii "p\0"	/* DW_AT_name */
++	.byte	2f - 1f	/* DW_AT_location: DW_FORM_block1 */
++1:
++	.byte	0xf2	/* DW_OP_GNU_implicit_pointer */
++	.4byte	.Lvar_out - d	/* referenced DIE */
++	.sleb128	0	/* offset */
++2:
++	.4byte	.Ltype_structptr - d	/* DW_AT_type */
++
++	.byte	0x0	/* end of children of main */
++
++	.byte	0x0	/* end of children of CU */
++debug_end:
++
++	.section	.debug_abbrev
++.Ldebug_abbrev0:
++
++	.uleb128 0x1	/* (abbrev code) */
++	.uleb128 0x11	/* (TAG: DW_TAG_compile_unit) */
++	.byte	0x1	/* DW_children_yes */
++	.uleb128 0x25	/* (DW_AT_producer) */
++	.uleb128 0x8	/* (DW_FORM_string) */
++	.uleb128 0x13	/* (DW_AT_language) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.uleb128 0x3	/* (DW_AT_name) */
++	.uleb128 0x8	/* (DW_FORM_string) */
++	.byte	0x0
++	.byte	0x0
++
++	.uleb128 0x2	/* (abbrev code) */
++	.uleb128 0x13	/* (TAG: DW_TAG_structure_type) */
++	.byte	0x1	/* DW_children_yes */
++	.uleb128 0x3	/* (DW_AT_name) */
++	.uleb128 0x8	/* (DW_FORM_string) */
++	.uleb128 0xb	/* (DW_AT_byte_size) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.byte	0
++	.byte	0
++
++	.uleb128 0x3	/* (abbrev code) */
++	.uleb128 0xd	/* (TAG: DW_TAG_member) */
++	.byte	0	/* DW_children_no */
++	.uleb128 0x3	/* (DW_AT_name) */
++	.uleb128 0x8	/* (DW_FORM_string) */
++	.uleb128 0x49	/* (DW_AT_type) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.uleb128 0x38	/* (DW_AT_data_member_location) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.byte	0
++	.byte	0
++
++	.uleb128 0x4	/* (abbrev code) */
++	.uleb128 0x34	/* (TAG: DW_TAG_variable) */
++	.byte	0x0	/* DW_children_yes */
++	.uleb128 0x3	/* (DW_AT_name) */
++	.uleb128 0x8	/* (DW_FORM_string) */
++	.uleb128 0x02	/* (DW_AT_location) */
++	.uleb128 0xa	/* (DW_FORM_block1) */
++	.uleb128 0x49	/* (DW_AT_type) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.byte	0x0
++	.byte	0x0
++
++	.uleb128 0x5	/* (abbrev code) */
++	.uleb128 0xf	/* (TAG: DW_TAG_pointer_type) */
++	.byte	0x0	/* DW_children_no */
++	.uleb128 0xb	/* (DW_AT_byte_size) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.uleb128 0x49	/* (DW_AT_type) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.byte	0x0
++	.byte	0x0
++
++	.uleb128	6			/* Abbrev code */
++	.uleb128	0x2e			/* DW_TAG_subprogram */
++	.byte		1			/* has_children */
++	.uleb128	0x3			/* DW_AT_name */
++	.uleb128	0x8			/* DW_FORM_string */
++	.uleb128	0x11			/* DW_AT_low_pc */
++	.uleb128	0x1			/* DW_FORM_addr */
++	.uleb128	0x12			/* DW_AT_high_pc */
++	.uleb128	0x1			/* DW_FORM_addr */
++	.uleb128	0x49			/* DW_AT_type */
++	.uleb128	0x13			/* DW_FORM_ref4 */
++	.uleb128	0x3f			/* DW_AT_external */
++	.uleb128	0xc			/* DW_FORM_flag */
++	.byte		0x0			/* Terminator */
++	.byte		0x0			/* Terminator */
++
++	.uleb128 0x7	/* (abbrev code) */
++	.uleb128 0x24	/* (TAG: DW_TAG_base_type) */
++	.byte	0	/* DW_children_no */
++	.uleb128 0xb	/* (DW_AT_byte_size) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.uleb128 0x3e	/* (DW_AT_encoding) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.uleb128 0x3	/* (DW_AT_name) */
++	.uleb128 0x8	/* (DW_FORM_string) */
++	.byte	0
++	.byte	0
++
++	.byte	0x0
+--- /dev/null
++++ b/gdb/testsuite/gdb.dwarf2/implptr-optimized-out.exp
+@@ -0,0 +1,37 @@
++# Copyright 2011 Free Software Foundation, Inc.
++
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program.  If not, see <http://www.gnu.org/licenses/>.
++load_lib dwarf.exp
++
++# This test can only be run on targets which support DWARF-2 and use gas.
++if {![dwarf2_support]} {
++    return 0  
++}
++
++set testfile "implptr-optimized-out"
++set srcfile ${testfile}.S
++set mainfile main.c
++set executable ${testfile}
++set binfile ${objdir}/${subdir}/${executable}
++
++if [prepare_for_testing ${testfile}.exp $executable "${srcfile} ${mainfile}" {}] {
++    return -1
++}
++
++# DW_OP_GNU_implicit_pointer implementation requires a valid frame.
++if ![runto_main] {
++    return -1
++}
++
++gdb_test "p p->f" " = <optimized out>"
+
diff --git a/gdb-vla-frame-set.patch b/gdb-vla-frame-set.patch
new file mode 100644
index 0000000..87ddca1
--- /dev/null
+++ b/gdb-vla-frame-set.patch
@@ -0,0 +1,91 @@
+commit 51dab9e418741ac7065cd5a6ec9b57285e90227c
+https://bugzilla.redhat.com/show_bug.cgi?id=738482
+
+--- a/gdb/printcmd.c
++++ b/gdb/printcmd.c
+@@ -1981,6 +1981,10 @@ print_variable_and_value (const char *name, struct symbol *var,
+       struct value_print_options opts;
+ 
+       val = read_var_value (var, frame);
++
++      make_cleanup_restore_selected_frame ();
++      select_frame (frame);
++
+       get_user_print_options (&opts);
+       common_val_print (val, stream, indent, &opts, current_language);
+     }
+--- /dev/null
++++ b/gdb/testsuite/gdb.base/vla-frame.c
+@@ -0,0 +1,31 @@
++/* This testcase is part of GDB, the GNU debugger.
++
++   Copyright 2011 Free Software Foundation, Inc.
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 3 of the License, or
++   (at your option) any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
++
++#include <string.h>
++
++int
++main (int argc, char **argv)
++{
++  char s[2 + argc];
++  void (*f) (char *) = 0;
++
++  memset (s, 0, sizeof (s));
++  s[0] = 'X';
++
++  f (s);
++  return 0;
++}
+--- /dev/null
++++ b/gdb/testsuite/gdb.base/vla-frame.exp
+@@ -0,0 +1,38 @@
++# Copyright 2011 Free Software Foundation, Inc.
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program.  If not, see <http://www.gnu.org/licenses/>.
++
++set testfile vla-frame
++set executable ${testfile}
++
++if { [prepare_for_testing ${testfile}.exp ${executable}] } {
++    return -1
++}
++
++if ![runto_main] {
++    return -1
++}
++
++set test "continue"
++gdb_test_multiple $test $test {
++    -re "Continuing\\.\r\n\r\nProgram received signal SIGSEGV, Segmentation fault\\.\r\n0x0+ in \\?\\? \\(\\)\r\n$gdb_prompt $" {
++	pass $test
++    }
++    -re "\r\n$gdb_prompt $" {
++	untested ${testfile}.exp
++	return
++    }
++}
++
++gdb_test "bt full" "\r\n +s = \"X\\\\000\"\r\n.*"
diff --git a/gdb.spec b/gdb.spec
index 4a1f20f..502b161 100644
--- a/gdb.spec
+++ b/gdb.spec
@@ -27,7 +27,7 @@ Version: 7.3.50.20110722
 
 # 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: 6%{?_with_upstream:.upstream}%{?dist}
+Release: 7%{?_with_upstream:.upstream}%{?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
@@ -543,6 +543,16 @@ Patch627: gdb-glibc-vdso-workaround.patch
 # [TUI] Fix stepi on stripped code.
 Patch628: gdb-tui-strip-stepi.patch
 
+# [vla] Fix VLA arrays displayed in `bt full' (BZ 738482).
+Patch629: gdb-vla-frame-set.patch
+
+# Fix DW_OP_GNU_implicit_pointer for DWARF32 v3+ on 64-bit arches.
+Patch630: gdb-implptr-64bit-1of2.patch
+Patch631: gdb-implptr-64bit-2of2.patch
+
+# Fix internal error on some optimized-out values.
+Patch632: gdb-optimized-out-internal-error.patch
+
 BuildRequires: ncurses-devel%{?_isa} texinfo gettext flex bison expat-devel%{?_isa}
 # --without-system-readline
 # Requires: readline%{?_isa}
@@ -811,6 +821,10 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c
 %patch619 -p1
 %patch627 -p1
 %patch628 -p1
+%patch629 -p1
+%patch630 -p1
+%patch631 -p1
+%patch632 -p1
 
 %patch393 -p1
 %patch335 -p1
@@ -1233,6 +1247,11 @@ fi
 %{_infodir}/gdb.info*
 
 %changelog
+* Mon Sep 26 2011 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.3.50.20110722-7.fc16
+- [vla] Fix VLA arrays displayed in `bt full' (BZ 738482).
+- Fix DW_OP_GNU_implicit_pointer for DWARF32 v3+ on 64-bit arches.
+- Fix internal error on some optimized-out values.
+
 * Tue Aug 16 2011 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.3.50.20110722-6.fc16
 - Python command/function auto-loading (Phil Muldoon, BZ 730976).
 - Work around PR libc/13097 "linux-vdso.so.1" warning message.


More information about the scm-commits mailing list