[patch] Handle DW_OP_GNU_const_index

Doug Evans dje@google.com
Tue Jun 19 00:44:00 GMT 2012


On Thu, Jun 14, 2012 at 1:17 PM, Doug Evans <dje@google.com> wrote:
> Hi.
>
> fyi, I will be checking this in once the corresponding change
> to include/dwarf2.def is approved on the gcc side
> (and the change is brought over to src).

Here is what I committed.

2012-06-18  Doug Evans  <dje@google.com>

        * dwarf2expr.c (execute_stack_op): Handle DW_OP_GNU_const_index.
        Adjust address for DW_OP_GNU_addr_index.
        * dwarf2expr.h (dwarf_expr_context): Update comment.
        * dwarf2loc.c (locexpr_describe_location_piece): New arg per_cu,
        all callers updated.  Handle TLS vars described with
        DW_OP_GNU_const_index.
        (disassemble_dwarf_expression): Handle DW_OP_GNU_addr_index
        and DW_OP_GNU_const_index.
        * dwarf2read.c (decode_locdesc): Handle DW_OP_GNU_addr_index.
-------------- next part --------------
2012-06-18  Doug Evans  <dje@google.com>

	* dwarf2expr.c (execute_stack_op): Handle DW_OP_GNU_const_index.
	Adjust address for DW_OP_GNU_addr_index.
	* dwarf2expr.h (dwarf_expr_context): Update comment.
	* dwarf2loc.c (locexpr_describe_location_piece): New arg per_cu,
	all callers updated.  Handle TLS vars described with
	DW_OP_GNU_const_index.
	(disassemble_dwarf_expression): Handle DW_OP_GNU_addr_index
	and DW_OP_GNU_const_index.
	* dwarf2read.c (decode_locdesc): Handle DW_OP_GNU_addr_index.

Index: dwarf2expr.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2expr.c,v
retrieving revision 1.86
diff -u -p -r1.86 dwarf2expr.c
--- dwarf2expr.c	17 Jun 2012 19:53:52 -0000	1.86
+++ dwarf2expr.c	19 Jun 2012 00:11:31 -0000
@@ -727,6 +727,12 @@ execute_stack_op (struct dwarf_expr_cont
 	case DW_OP_GNU_addr_index:
 	  op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
 	  result = (ctx->funcs->get_addr_index) (ctx->baton, uoffset);
+	  result += ctx->offset;
+	  result_val = value_from_ulongest (address_type, result);
+	  break;
+	case DW_OP_GNU_const_index:
+	  op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
+	  result = (ctx->funcs->get_addr_index) (ctx->baton, uoffset);
 	  result_val = value_from_ulongest (address_type, result);
 	  break;
 
Index: dwarf2expr.h
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2expr.h,v
retrieving revision 1.49
diff -u -p -r1.49 dwarf2expr.h
--- dwarf2expr.h	17 Jun 2012 19:50:52 -0000	1.49
+++ dwarf2expr.h	19 Jun 2012 00:11:31 -0000
@@ -158,7 +158,7 @@ struct dwarf_expr_context
      context and operations depending on DW_FORM_ref_addr are not allowed.  */
   int ref_addr_size;
 
-  /* Offset used to relocate DW_OP_addr argument.  */
+  /* Offset used to relocate DW_OP_addr and DW_OP_GNU_addr_index arguments.  */
   CORE_ADDR offset;
 
   /* An opaque argument provided by the caller, which will be passed
Index: dwarf2loc.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2loc.c,v
retrieving revision 1.150
diff -u -p -r1.150 dwarf2loc.c
--- dwarf2loc.c	17 Jun 2012 19:53:52 -0000	1.150
+++ dwarf2loc.c	19 Jun 2012 00:11:31 -0000
@@ -3293,10 +3293,12 @@ locexpr_regname (struct gdbarch *gdbarch
 static const gdb_byte *
 locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
 				 CORE_ADDR addr, struct objfile *objfile,
+				 struct dwarf2_per_cu_data *per_cu,
 				 const gdb_byte *data, const gdb_byte *end,
 				 unsigned int addr_size)
 {
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  size_t leb128_size;
 
   if (data[0] >= DW_OP_reg0 && data[0] <= DW_OP_reg31)
     {
@@ -3416,6 +3418,29 @@ locexpr_describe_location_piece (struct 
 
       data += 1 + addr_size + 1;
     }
+
+  /* With -gsplit-dwarf a TLS variable can also look like this:
+     DW_AT_location    : 3 byte block: fc 4 e0
+                        (DW_OP_GNU_const_index: 4;
+			 DW_OP_GNU_push_tls_address)  */
+  else if (data + 3 <= end
+	   && data + 1 + (leb128_size = skip_leb128 (data + 1, end)) < end
+	   && data[0] == DW_OP_GNU_const_index
+	   && leb128_size > 0
+	   && data[1 + leb128_size] == DW_OP_GNU_push_tls_address
+	   && piece_end_p (data + 2 + leb128_size, end))
+    {
+      ULONGEST offset;
+
+      data = safe_read_uleb128 (data + 1, end, &offset);
+      offset = dwarf2_read_addr_index (per_cu, offset);
+      fprintf_filtered (stream, 
+			_("a thread-local variable at offset 0x%s "
+			  "in the thread-local storage for `%s'"),
+			phex_nz (offset, addr_size), objfile->name);
+      ++data;
+    }
+
   else if (data[0] >= DW_OP_lit0
 	   && data[0] <= DW_OP_lit31
 	   && data + 1 < end
@@ -3771,6 +3796,17 @@ disassemble_dwarf_expression (struct ui_
 					all, per_cu);
 	  data += ul;
 	  continue;
+
+	case DW_OP_GNU_addr_index:
+	  data = safe_read_uleb128 (data, end, &ul);
+	  ul = dwarf2_read_addr_index (per_cu, ul);
+	  fprintf_filtered (stream, " 0x%s", phex_nz (ul, addr_size));
+	  break;
+	case DW_OP_GNU_const_index:
+	  data = safe_read_uleb128 (data, end, &ul);
+	  ul = dwarf2_read_addr_index (per_cu, ul);
+	  fprintf_filtered (stream, " %s", pulongest (ul));
+	  break;
 	}
 
       fprintf_filtered (stream, "\n");
@@ -3805,7 +3841,7 @@ locexpr_describe_location_1 (struct symb
       if (!dwarf2_always_disassemble)
 	{
 	  data = locexpr_describe_location_piece (symbol, stream,
-						  addr, objfile,
+						  addr, objfile, per_cu,
 						  data, end, addr_size);
 	  /* If we printed anything, or if we have an empty piece,
 	     then don't disassemble.  */
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.664
diff -u -p -r1.664 dwarf2read.c
--- dwarf2read.c	17 Jun 2012 19:53:52 -0000	1.664
+++ dwarf2read.c	19 Jun 2012 00:11:31 -0000
@@ -15512,6 +15512,7 @@ decode_locdesc (struct dwarf_block *blk,
 	  break;
 
 	case DW_OP_GNU_addr_index:
+	case DW_OP_GNU_const_index:
 	  stack[++stacki] = read_addr_index_from_leb128 (cu, &data[i],
 							 &bytes_read);
 	  i += bytes_read;


More information about the Gdb-patches mailing list