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]

[commit] [patch#2] fetch result of locdesc expressions as integer (not address)


On Mon, 17 Oct 2011 09:13:00 +0200, Tristan Gingold wrote:
> On Oct 17, 2011, at 1:32 AM, Joel Brobecker wrote:
> > What we could perhaps try is to push 'integer-to-address(0)', rather
> > than zero itself.  Then, if we want the offset, then subtract that
> > same integer-to-address(0) value from the result.
+
> SRAM address 0 is valid, but if you convert NULL to a non-0 value, many
> things get broken!

You can see the Joel's idea does not work due to it.  The very first field
stays at 0 while every other field gets shifted by 0x800000.

I believe the NULL exception should be in specific cases at the callers.

One would have to create some 0xdeadf00d artificial address as the base struct
address but I do not think one can create arbitrary addresses as on gdbarches
it may not be a valid address.

Just there is no real reason to keep the patch in place now, I should review
it after some form of archer-jankratochvil-vla gets in.

Filed a new KFAIL-tracker:
	Support DW_AT_location complex DWARF expressions
	http://sourceware.org/bugzilla/show_bug.cgi?id=13307

and checked in the reversion.


Sorry,
Jan


http://sourceware.org/ml/gdb-cvs/2011-10/msg00132.html

--- src/gdb/ChangeLog	2011/10/16 19:40:36	1.13439
+++ src/gdb/ChangeLog	2011/10/17 12:57:13	1.13440
@@ -1,3 +1,13 @@
+2011-10-17  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	Revert:
+	2011-07-27  Jan Kratochvil  <jan.kratochvil@redhat.com>
+        * dwarf2expr.c (ctx_no_read_reg): New function.
+        * dwarf2expr.h (ctx_no_read_reg): New declaration.
+        * dwarf2read.c (read_2_signed_bytes, read_4_signed_bytes): Remove.
+        (decode_locdesc_read_mem, decode_locdesc_ctx_funcs): New.
+        (decode_locdesc): Replace by a caller of dwarf_expr_eval.
+
 2011-10-16  Doug Evans  <dje@google.com>
 
 	* NEWS: Document python gdb.printing.register_pretty_printer's new
--- src/gdb/testsuite/ChangeLog	2011/10/16 08:42:02	1.2899
+++ src/gdb/testsuite/ChangeLog	2011/10/17 12:57:15	1.2900
@@ -1,3 +1,11 @@
+2011-10-17  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* gdb.dwarf2/dw2-simple-locdesc.exp (p &s.shl): KFAIL it.
+	Revert the part of:
+	2011-07-27  Jan Kratochvil  <jan.kratochvil@redhat.com>
+	* gdb.dwarf2/dw2-stack-boundary.exp (check partial symtab errors):
+	Change the expected string.
+
 2011-10-16  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
 	Fix results with system glibc debug info installed.
--- src/gdb/dwarf2expr.c	2011/10/09 19:43:40	1.76
+++ src/gdb/dwarf2expr.c	2011/10/17 12:57:14	1.77
@@ -1471,14 +1471,6 @@
   gdb_assert (ctx->recursion_depth >= 0);
 }
 
-/* Stub dwarf_expr_context_funcs.read_reg implementation.  */
-
-CORE_ADDR
-ctx_no_read_reg (void *baton, int regnum)
-{
-  error (_("Registers access is invalid in this context"));
-}
-
 /* Stub dwarf_expr_context_funcs.get_frame_base implementation.  */
 
 void
--- src/gdb/dwarf2expr.h	2011/10/09 19:43:40	1.41
+++ src/gdb/dwarf2expr.h	2011/10/17 12:57:14	1.42
@@ -270,7 +270,6 @@
 
 /* Stub dwarf_expr_context_funcs implementations.  */
 
-CORE_ADDR ctx_no_read_reg (void *baton, int regnum);
 void ctx_no_get_frame_base (void *baton, const gdb_byte **start,
 			    size_t *length);
 CORE_ADDR ctx_no_get_frame_cfa (void *baton);
--- src/gdb/dwarf2read.c	2011/10/13 09:36:47	1.573
+++ src/gdb/dwarf2read.c	2011/10/17 12:57:14	1.574
@@ -10297,12 +10297,24 @@
   return bfd_get_16 (abfd, buf);
 }
 
+static int
+read_2_signed_bytes (bfd *abfd, gdb_byte *buf)
+{
+  return bfd_get_signed_16 (abfd, buf);
+}
+
 static unsigned int
 read_4_bytes (bfd *abfd, gdb_byte *buf)
 {
   return bfd_get_32 (abfd, buf);
 }
 
+static int
+read_4_signed_bytes (bfd *abfd, gdb_byte *buf)
+{
+  return bfd_get_signed_32 (abfd, buf);
+}
+
 static ULONGEST
 read_8_bytes (bfd *abfd, gdb_byte *buf)
 {
@@ -14419,37 +14431,6 @@
   dwarf2_per_objfile->read_in_chain = &type_sig->per_cu;
 }
 
-/* Workaround as dwarf_expr_context_funcs.read_mem implementation before
-   a proper runtime DWARF expressions evaluator gets implemented.
-   Otherwise gnuv3_baseclass_offset would error by:
-   Expected a negative vbase offset (old compiler?)  */
-
-static void
-decode_locdesc_read_mem (void *baton, gdb_byte *buf, CORE_ADDR addr,
-			 size_t length)
-{
-  struct dwarf_expr_context *ctx = baton;
-  struct gdbarch *gdbarch = ctx->gdbarch;
-  struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
-
-  memset (buf, 0, length);
-
-  if (TYPE_LENGTH (ptr_type) == length)
-    store_typed_address (buf, ptr_type, addr);
-}
-
-static const struct dwarf_expr_context_funcs decode_locdesc_ctx_funcs =
-{
-  ctx_no_read_reg,
-  decode_locdesc_read_mem,
-  ctx_no_get_frame_base,
-  ctx_no_get_frame_cfa,
-  ctx_no_get_frame_pc,
-  ctx_no_get_tls_address,
-  ctx_no_dwarf_call,
-  ctx_no_get_base_type
-};
-
 /* Decode simple location descriptions.
    Given a pointer to a dwarf block that defines a location, compute
    the location and return the value.
@@ -14467,60 +14448,235 @@
    object is optimized out.  The return value is 0 for that case.
    FIXME drow/2003-11-16: No callers check for this case any more; soon all
    callers will only want a very basic result and this can become a
-   complaint.  */
+   complaint.
+
+   Note that stack[0] is unused except as a default error return.  */
 
 static CORE_ADDR
 decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
-  struct dwarf_expr_context *ctx;
-  struct cleanup *old_chain;
-  volatile struct gdb_exception ex;
+  int i;
+  int size = blk->size;
+  gdb_byte *data = blk->data;
+  CORE_ADDR stack[64];
+  int stacki;
+  unsigned int bytes_read, unsnd;
+  gdb_byte op;
 
-  ctx = new_dwarf_expr_context ();
-  old_chain = make_cleanup_free_dwarf_expr_context (ctx);
-  make_cleanup_value_free_to_mark (value_mark ());
+  i = 0;
+  stacki = 0;
+  stack[stacki] = 0;
+  stack[++stacki] = 0;
 
-  ctx->gdbarch = get_objfile_arch (objfile);
-  ctx->addr_size = cu->header.addr_size;
-  ctx->ref_addr_size = dwarf2_per_cu_ref_addr_size (cu->per_cu);
-  ctx->offset = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
-  ctx->baton = ctx;
-  ctx->funcs = &decode_locdesc_ctx_funcs;
+  while (i < size)
+    {
+      op = data[i++];
+      switch (op)
+	{
+	case DW_OP_lit0:
+	case DW_OP_lit1:
+	case DW_OP_lit2:
+	case DW_OP_lit3:
+	case DW_OP_lit4:
+	case DW_OP_lit5:
+	case DW_OP_lit6:
+	case DW_OP_lit7:
+	case DW_OP_lit8:
+	case DW_OP_lit9:
+	case DW_OP_lit10:
+	case DW_OP_lit11:
+	case DW_OP_lit12:
+	case DW_OP_lit13:
+	case DW_OP_lit14:
+	case DW_OP_lit15:
+	case DW_OP_lit16:
+	case DW_OP_lit17:
+	case DW_OP_lit18:
+	case DW_OP_lit19:
+	case DW_OP_lit20:
+	case DW_OP_lit21:
+	case DW_OP_lit22:
+	case DW_OP_lit23:
+	case DW_OP_lit24:
+	case DW_OP_lit25:
+	case DW_OP_lit26:
+	case DW_OP_lit27:
+	case DW_OP_lit28:
+	case DW_OP_lit29:
+	case DW_OP_lit30:
+	case DW_OP_lit31:
+	  stack[++stacki] = op - DW_OP_lit0;
+	  break;
+
+	case DW_OP_reg0:
+	case DW_OP_reg1:
+	case DW_OP_reg2:
+	case DW_OP_reg3:
+	case DW_OP_reg4:
+	case DW_OP_reg5:
+	case DW_OP_reg6:
+	case DW_OP_reg7:
+	case DW_OP_reg8:
+	case DW_OP_reg9:
+	case DW_OP_reg10:
+	case DW_OP_reg11:
+	case DW_OP_reg12:
+	case DW_OP_reg13:
+	case DW_OP_reg14:
+	case DW_OP_reg15:
+	case DW_OP_reg16:
+	case DW_OP_reg17:
+	case DW_OP_reg18:
+	case DW_OP_reg19:
+	case DW_OP_reg20:
+	case DW_OP_reg21:
+	case DW_OP_reg22:
+	case DW_OP_reg23:
+	case DW_OP_reg24:
+	case DW_OP_reg25:
+	case DW_OP_reg26:
+	case DW_OP_reg27:
+	case DW_OP_reg28:
+	case DW_OP_reg29:
+	case DW_OP_reg30:
+	case DW_OP_reg31:
+	  stack[++stacki] = op - DW_OP_reg0;
+	  if (i < size)
+	    dwarf2_complex_location_expr_complaint ();
+	  break;
+
+	case DW_OP_regx:
+	  unsnd = read_unsigned_leb128 (NULL, (data + i), &bytes_read);
+	  i += bytes_read;
+	  stack[++stacki] = unsnd;
+	  if (i < size)
+	    dwarf2_complex_location_expr_complaint ();
+	  break;
+
+	case DW_OP_addr:
+	  stack[++stacki] = read_address (objfile->obfd, &data[i],
+					  cu, &bytes_read);
+	  i += bytes_read;
+	  break;
+
+	case DW_OP_const1u:
+	  stack[++stacki] = read_1_byte (objfile->obfd, &data[i]);
+	  i += 1;
+	  break;
+
+	case DW_OP_const1s:
+	  stack[++stacki] = read_1_signed_byte (objfile->obfd, &data[i]);
+	  i += 1;
+	  break;
+
+	case DW_OP_const2u:
+	  stack[++stacki] = read_2_bytes (objfile->obfd, &data[i]);
+	  i += 2;
+	  break;
+
+	case DW_OP_const2s:
+	  stack[++stacki] = read_2_signed_bytes (objfile->obfd, &data[i]);
+	  i += 2;
+	  break;
+
+	case DW_OP_const4u:
+	  stack[++stacki] = read_4_bytes (objfile->obfd, &data[i]);
+	  i += 4;
+	  break;
+
+	case DW_OP_const4s:
+	  stack[++stacki] = read_4_signed_bytes (objfile->obfd, &data[i]);
+	  i += 4;
+	  break;
+
+	case DW_OP_constu:
+	  stack[++stacki] = read_unsigned_leb128 (NULL, (data + i),
+						  &bytes_read);
+	  i += bytes_read;
+	  break;
+
+	case DW_OP_consts:
+	  stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read);
+	  i += bytes_read;
+	  break;
+
+	case DW_OP_dup:
+	  stack[stacki + 1] = stack[stacki];
+	  stacki++;
+	  break;
+
+	case DW_OP_plus:
+	  stack[stacki - 1] += stack[stacki];
+	  stacki--;
+	  break;
+
+	case DW_OP_plus_uconst:
+	  stack[stacki] += read_unsigned_leb128 (NULL, (data + i),
+						 &bytes_read);
+	  i += bytes_read;
+	  break;
+
+	case DW_OP_minus:
+	  stack[stacki - 1] -= stack[stacki];
+	  stacki--;
+	  break;
+
+	case DW_OP_deref:
+	  /* If we're not the last op, then we definitely can't encode
+	     this using GDB's address_class enum.  This is valid for partial
+	     global symbols, although the variable's address will be bogus
+	     in the psymtab.  */
+	  if (i < size)
+	    dwarf2_complex_location_expr_complaint ();
+	  break;
+
+        case DW_OP_GNU_push_tls_address:
+	  /* The top of the stack has the offset from the beginning
+	     of the thread control block at which the variable is located.  */
+	  /* Nothing should follow this operator, so the top of stack would
+	     be returned.  */
+	  /* This is valid for partial global symbols, but the variable's
+	     address will be bogus in the psymtab.  */
+	  if (i < size)
+	    dwarf2_complex_location_expr_complaint ();
+          break;
 
-  /* DW_AT_data_member_location expects the structure address to be pushed on
-     the stack.  Simulate the offset by address 0.  */
-  dwarf_expr_push_address (ctx, 0, 0);
+	case DW_OP_GNU_uninit:
+	  break;
 
-  TRY_CATCH (ex, RETURN_MASK_ERROR)
-    {
-      dwarf_expr_eval (ctx, blk->data, blk->size);
-    }
-  if (ex.reason < 0)
-    {
-      if (ex.message)
-	complaint (&symfile_complaints, "%s", ex.message);
-    }
-  else if (ctx->num_pieces == 0)
-    switch (ctx->location)
-      {
-      /* The returned number will be bogus, just do not complain for locations
-	 in global registers - it is here only a partial symbol address.  */
-      case DWARF_VALUE_REGISTER:
+	default:
+	  {
+	    const char *name = dwarf_stack_op_name (op);
 
-      case DWARF_VALUE_MEMORY:
-      case DWARF_VALUE_STACK:
-	{
-	  CORE_ADDR address = dwarf_expr_fetch_address (ctx, 0);
+	    if (name)
+	      complaint (&symfile_complaints, _("unsupported stack op: '%s'"),
+			 name);
+	    else
+	      complaint (&symfile_complaints, _("unsupported stack op: '%02x'"),
+			 op);
+	  }
 
-	  do_cleanups (old_chain);
-	  return address;
+	  return (stack[stacki]);
 	}
-      }
 
-  do_cleanups (old_chain);
-  dwarf2_complex_location_expr_complaint ();
-  return 0;
+      /* Enforce maximum stack depth of SIZE-1 to avoid writing
+         outside of the allocated space.  Also enforce minimum>0.  */
+      if (stacki >= ARRAY_SIZE (stack) - 1)
+	{
+	  complaint (&symfile_complaints,
+		     _("location description stack overflow"));
+	  return 0;
+	}
+
+      if (stacki <= 0)
+	{
+	  complaint (&symfile_complaints,
+		     _("location description stack underflow"));
+	  return 0;
+	}
+    }
+  return (stack[stacki]);
 }
 
 /* memory allocation interface */
--- src/gdb/testsuite/gdb.dwarf2/dw2-simple-locdesc.exp	2011/07/27 21:18:40	1.2
+++ src/gdb/testsuite/gdb.dwarf2/dw2-simple-locdesc.exp	2011/10/17 12:57:15	1.3
@@ -32,7 +32,15 @@
 
 # Re: [patch 2/2] Fix decode_locdesc for gcc-4.7.x optimized DWARF
 # http://sourceware.org/ml/gdb-patches/2011-07/msg00766.html
-gdb_test "p &s.shl" { = \(int \*\) 0x1000000}
+set test "p &s.shl"
+gdb_test_multiple $test $test {
+    -re " = \\(int \\*\\) 0x1000000\r\n$gdb_prompt $" {
+	pass $test
+    }
+    -re " = \\(int \\*\\) 0x14\r\n$gdb_prompt $" {
+	kfail "symtab/13307" $test
+    }
+}
 
 # Re: RFC: fix DW_AT_data_member_location buglet
 # http://sourceware.org/ml/gdb-patches/2011-05/msg00291.html
--- src/gdb/testsuite/gdb.dwarf2/dw2-stack-boundary.exp	2011/07/27 17:08:06	1.4
+++ src/gdb/testsuite/gdb.dwarf2/dw2-stack-boundary.exp	2011/10/17 12:57:15	1.5
@@ -41,7 +41,7 @@
     }
 }
 gdb_test_no_output "set complaints 100"
-gdb_test "file $binfile" {Reading symbols from .*\.\.\.Asked for position 0 of stack, stack only has 0 elements on it\..*\.\.\.done\.} "check partial symtab errors"
+gdb_test "file $binfile" {Reading symbols from .*\.\.\.location description stack underflow\.\.\.location description stack overflow\.\.\.done\.} "check partial symtab errors"
 
 gdb_test "p underflow" {Asked for position 0 of stack, stack only has 0 elements on it\.}
 gdb_test "p overflow" " = 2"


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