This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFC: fix bug in DW_OP_GNU_implicit_pointer


Doug pointed out to me a while ago that DW_OP_GNU_implicit_pointer is
specified as taking a section offset as an argument, but gdb implements
it as taking a CU offset.  See:

    http://www.dwarfstd.org/ShowIssue.php?issue=100831.1&type=open

This patch fixes the bug.

I updated the implptr-64bit test case to test the new code as well.

Built and regtested on x86-64 Fedora 16.

Let me know what you think; otherwise I plan to check it in.

Tom

2012-11-30  Tom Tromey  <tromey@redhat.com>

	* dwarf2read.c (dwarf2_fetch_die_location_block_section): New
	function.
	(dwarf2_fetch_die_location_block): Rewrite to use it.
	* dwarf2loc.h (dwarf2_fetch_die_location_block_section): Declare.
	* dwarf2loc.c (indirect_pieced_value): Use
	dwarf2_fetch_die_location_block_section.
	* dwarf2expr.h (struct dwarf_expr_context) <len, data>: Update
	comment.
	(struct dwarf_expr_piece) <v.ptr.die>: Now a sect_offset.
	* dwarf2expr.c (add_piece): Update.
	(execute_stack_op) <DW_OP_GNU_implicit_pointer>: Update comment.

2012-11-30  Tom Tromey  <tromey@redhat.com>

	* 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..7c29413 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -2034,9 +2034,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_location_block_section (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,
diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h
index 0f10767..5aa0abd 100644
--- a/gdb/dwarf2loc.h
+++ b/gdb/dwarf2loc.h
@@ -62,6 +62,11 @@ const gdb_byte *dwarf2_find_location_expression
    size_t *locexpr_length,
    CORE_ADDR pc);
 
+struct dwarf2_locexpr_baton dwarf2_fetch_die_location_block_section
+  (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_location_block
   (cu_offset offset_in_cu, struct dwarf2_per_cu_data *per_cu,
    CORE_ADDR (*get_frame_pc) (void *baton),
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index f4bd7a9..5be051e 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_location_block_section (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,21 @@ dwarf2_fetch_die_location_block (cu_offset offset_in_cu,
   return retval;
 }
 
+/* Like dwarf2_fetch_die_location_block_section, but take a CU
+   offset.  */
+
+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)
+{
+  sect_offset offset = { per_cu->offset.sect_off + offset_in_cu.cu_off };
+
+  return dwarf2_fetch_die_location_block_section (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..bd15c35 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
@@ -45,7 +45,11 @@ proc test { dwarf_version offset_size addr_size ref_addr_size } {
 }
 
 #    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
+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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]