This is the mail archive of the archer@sourceware.org mailing list for the Archer 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]

Re: Calculating array length


Op zondag 07-06-2009 om 19:49 uur [tijdzone +0200], schreef Jan
Kratochvil:

> > Thereafter val_print_array_elements has to evaluate each element, by
> > setting object-addres to the right pointer, and then evaluate the
> length
> > of the string, evaluate the length and copy it to the inferior...
> 
> Yes, this is described in DWARF for DW_OP_push_object_address
>         This object may correspond to [...] a component of an array
> [...]
>         whose address has been dynamically determined by an earlier
> step
>         during user expression evaluation.
> 
> 
> > I have this all working,
> 
> Would you submit the patch to integrate it into
> archer-jankratochvil-vla?

I attached the patch. It always uses the bounds to decide how many
elements there are, and when necessary each element in the array is
evaluated seperately. 

To see if this is really neccessary to do, I test if
TYPE_DATA_LOCATION_DWARF_BLOCK is set. I doubt if that is ok, but it
works for my case.

Also pascal_cal_print is adapted so that it does not call check_typedef
on the type before it is passed to val_print_array_elements.

Not all cases are fixed now, but most are. What do you think of the
patch?

Joost
diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c
index 68ff54a..78f0b11 100644
--- a/gdb/p-valprint.c
+++ b/gdb/p-valprint.c
@@ -58,14 +58,15 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr,
 {
   unsigned int i = 0;	/* Number of characters printed */
   unsigned len;
-  struct type *elttype;
+  struct type *elttype, *cleantype;
   unsigned eltlen;
   int length_pos, length_size, string_pos;
   struct type *char_type;
   LONGEST val;
   CORE_ADDR addr;
 
-  CHECK_TYPEDEF (type);
+  cleantype = type;
+  type = check_typedef (type);
   switch (TYPE_CODE (type))
     {
     case TYPE_CODE_ARRAY:
@@ -119,7 +120,7 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr,
 		{
 		  i = 0;
 		}
-	      val_print_array_elements (type, valaddr + embedded_offset, address, stream,
+	      val_print_array_elements (cleantype, valaddr + embedded_offset, address, stream,
 					recurse, options, i);
 	      fprintf_filtered (stream, "}");
 	    }
diff --git a/gdb/valprint.c b/gdb/valprint.c
index 34b9422..bcf6f99 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -1049,36 +1049,49 @@ val_print_array_elements (struct type *type, const gdb_byte *valaddr,
 {
   unsigned int things_printed = 0;
   unsigned len;
-  struct type *elttype, *index_type;
+  struct type *elttype, *index_type, *clean_type;
   unsigned eltlen;
+  unsigned stride;
   /* Position of the array element we are examining to see
      whether it is repeated.  */
   unsigned int rep1;
   /* Number of repetitions we have detected so far.  */
   unsigned int reps;
   long low_bound_index = 0;
+  /* The real data-address, not the address of the descriptor */
+  CORE_ADDR addr_data_location;
 
   elttype = TYPE_TARGET_TYPE (type);
   eltlen = TYPE_LENGTH (check_typedef (elttype));
+
+  /* When check_typedef is called on a type, dynamic properties like the
+     array bounds are determined based on the corrent object_address. Once read,
+     those values can not be read again. So we need to store a clean copy
+     of the type so we can read this dynamic information later on. */
+  clean_type=type;
+  type = check_typedef(type);
+  stride = TYPE_ARRAY_BYTE_STRIDE_VALUE(type);
+  if (stride==0)
+    {
+      stride = eltlen;
+    }
   index_type = TYPE_INDEX_TYPE (type);
 
-  /* Compute the number of elements in the array.  On most arrays,
-     the size of its elements is not zero, and so the number of elements
-     is simply the size of the array divided by the size of the elements.
-     But for arrays of elements whose size is zero, we need to look at
-     the bounds.  */
-  if (eltlen != 0)
-    len = TYPE_LENGTH (type) / eltlen;
+  addr_data_location=address;
+  if (!object_address_get_data (type, &addr_data_location))
+    error (_("Attempt to take address of non-valid value."));
+
+  /* Always use the bounds to calculate the amount of
+     elements in the array.  */
+  long low, hi;
+  if (get_array_bounds (type, &low, &hi))
+    {
+      len = hi - low + 1;
+    }
   else
     {
-      long low, hi;
-      if (get_array_bounds (type, &low, &hi))
-        len = hi - low + 1;
-      else
-        {
-          warning (_("unable to get bounds of array, assuming null array"));
-          len = 0;
-        }
+      warning (_("unable to get bounds of array, assuming null array"));
+      len = 0;
     }
 
   /* Get the array low bound.  This only makes sense if the array
@@ -1118,10 +1131,23 @@ val_print_array_elements (struct type *type, const gdb_byte *valaddr,
 	  ++rep1;
 	}
 
+      if (TYPE_DATA_LOCATION_DWARF_BLOCK (elttype) != NULL)
+        {
+          /* Set object_address to the address of the element and create a
+             new, clean value to pass to common_val_print, so that all dyanic
+             properties are handled correctly. */
+          struct value *val;
+          object_address_set(addr_data_location + i * stride);
+          val = value_at_lazy(TYPE_TARGET_TYPE (clean_type),addr_data_location + i * stride);
+          common_val_print(val,stream,recurse +1, options, current_language);
+        }
+        else {
+	      val_print (elttype, valaddr + i * stride, 0, addr_data_location + i * stride,
+	                 stream, recurse + 1, options, current_language);
+        }
+
       if (reps > options->repeat_count_threshold)
 	{
-	  val_print (elttype, valaddr + i * eltlen, 0, address + i * eltlen,
-		     stream, recurse + 1, options, current_language);
 	  annotate_elt_rep (reps);
 	  fprintf_filtered (stream, " <repeats %u times>", reps);
 	  annotate_elt_rep_end ();
@@ -1131,8 +1157,6 @@ val_print_array_elements (struct type *type, const gdb_byte *valaddr,
 	}
       else
 	{
-	  val_print (elttype, valaddr + i * eltlen, 0, address + i * eltlen,
-		     stream, recurse + 1, options, current_language);
 	  annotate_elt ();
 	  things_printed++;
 	}

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