gdb/
* value.h (value_available_contents_eq): Declare. * value.c (find_first_range_overlap): New function. (value_available_contents_eq): New function. * valprint.c (val_print_array_elements): Use value_available_contents_eq. * ada-valprint.c (val_print_packed_array_elements): Use value_available_contents_eq. * jv-valprint.c (java_value_print): Use value_available_contents_eq.
This commit is contained in:
parent
e6e4e7014d
commit
c8c1c22fea
6 changed files with 151 additions and 6 deletions
|
@ -1,3 +1,15 @@
|
|||
2011-02-14 Pedro Alves <pedro@codesourcery.com>
|
||||
|
||||
* value.h (value_available_contents_eq): Declare.
|
||||
* value.c (find_first_range_overlap): New function.
|
||||
(value_available_contents_eq): New function.
|
||||
* valprint.c (val_print_array_elements): Use
|
||||
value_available_contents_eq.
|
||||
* ada-valprint.c (val_print_packed_array_elements): Use
|
||||
value_available_contents_eq.
|
||||
* jv-valprint.c (java_value_print): Use
|
||||
value_available_contents_eq.
|
||||
|
||||
2011-02-14 Pedro Alves <pedro@codesourcery.com>
|
||||
|
||||
* target.c (target_read_live_memory): New function.
|
||||
|
|
|
@ -200,7 +200,9 @@ val_print_packed_array_elements (struct type *type, const gdb_byte *valaddr,
|
|||
(i * bitsize) / HOST_CHAR_BIT,
|
||||
(i * bitsize) % HOST_CHAR_BIT,
|
||||
bitsize, elttype);
|
||||
if (memcmp (value_contents (v0), value_contents (v1), eltlen) != 0)
|
||||
if (!value_available_contents_eq (v0, value_embedded_offset (v0),
|
||||
v1, value_embedded_offset (v1),
|
||||
eltlen))
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -179,8 +179,11 @@ java_value_print (struct value *val, struct ui_file *stream,
|
|||
set_value_lazy (next_v, 1);
|
||||
set_value_offset (next_v, value_offset (next_v)
|
||||
+ TYPE_LENGTH (el_type));
|
||||
if (memcmp (value_contents (v), value_contents (next_v),
|
||||
TYPE_LENGTH (el_type)) != 0)
|
||||
value_fetch_lazy (next_v);
|
||||
if (!(value_available_contents_eq
|
||||
(v, value_embedded_offset (v),
|
||||
next_v, value_embedded_offset (next_v),
|
||||
TYPE_LENGTH (el_type))))
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1242,9 +1242,11 @@ val_print_array_elements (struct type *type,
|
|||
rep1 = i + 1;
|
||||
reps = 1;
|
||||
while (rep1 < len
|
||||
&& memcmp (valaddr + embedded_offset + i * eltlen,
|
||||
valaddr + embedded_offset + rep1 * eltlen,
|
||||
eltlen) == 0)
|
||||
&& value_available_contents_eq (val,
|
||||
embedded_offset + i * eltlen,
|
||||
val,
|
||||
embedded_offset + rep1 * eltlen,
|
||||
eltlen))
|
||||
{
|
||||
++reps;
|
||||
++rep1;
|
||||
|
|
101
gdb/value.c
101
gdb/value.c
|
@ -496,6 +496,107 @@ mark_value_bytes_unavailable (struct value *value, int offset, int length)
|
|||
}
|
||||
}
|
||||
|
||||
/* Find the first range in RANGES that overlaps the range defined by
|
||||
OFFSET and LENGTH, starting at element POS in the RANGES vector,
|
||||
Returns the index into RANGES where such overlapping range was
|
||||
found, or -1 if none was found. */
|
||||
|
||||
static int
|
||||
find_first_range_overlap (VEC(range_s) *ranges, int pos,
|
||||
int offset, int length)
|
||||
{
|
||||
range_s *r;
|
||||
int i;
|
||||
|
||||
for (i = pos; VEC_iterate (range_s, ranges, i, r); i++)
|
||||
if (ranges_overlap (r->offset, r->length, offset, length))
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
value_available_contents_eq (const struct value *val1, int offset1,
|
||||
const struct value *val2, int offset2,
|
||||
int length)
|
||||
{
|
||||
int org_len = length;
|
||||
int org_offset1 = offset1;
|
||||
int org_offset2 = offset2;
|
||||
int idx1 = 0, idx2 = 0;
|
||||
int prev_avail;
|
||||
|
||||
/* This routine is used by printing routines, where we should
|
||||
already have read the value. Note that we only know whether a
|
||||
value chunk is available if we've tried to read it. */
|
||||
gdb_assert (!val1->lazy && !val2->lazy);
|
||||
|
||||
/* The offset from either ORG_OFFSET1 or ORG_OFFSET2 where the
|
||||
available contents we haven't compared yet start. */
|
||||
prev_avail = 0;
|
||||
|
||||
while (length > 0)
|
||||
{
|
||||
range_s *r1, *r2;
|
||||
ULONGEST l1, h1;
|
||||
ULONGEST l2, h2;
|
||||
|
||||
idx1 = find_first_range_overlap (val1->unavailable, idx1,
|
||||
offset1, length);
|
||||
idx2 = find_first_range_overlap (val2->unavailable, idx2,
|
||||
offset2, length);
|
||||
|
||||
/* The usual case is for both values to be completely available. */
|
||||
if (idx1 == -1 && idx2 == -1)
|
||||
return (memcmp (val1->contents + org_offset1 + prev_avail,
|
||||
val2->contents + org_offset2 + prev_avail,
|
||||
org_len - prev_avail) == 0);
|
||||
/* The contents only match equal if the available set matches as
|
||||
well. */
|
||||
else if (idx1 == -1 || idx2 == -1)
|
||||
return 0;
|
||||
|
||||
gdb_assert (idx1 != -1 && idx2 != -1);
|
||||
|
||||
r1 = VEC_index (range_s, val1->unavailable, idx1);
|
||||
r2 = VEC_index (range_s, val2->unavailable, idx2);
|
||||
|
||||
/* Get the unavailable windows intersected by the incoming
|
||||
ranges. The first and last ranges that overlap the argument
|
||||
range may be wider than said incoming arguments ranges. */
|
||||
l1 = max (offset1, r1->offset);
|
||||
h1 = min (offset1 + length, r1->offset + r1->length);
|
||||
|
||||
l2 = max (offset2, r2->offset);
|
||||
h2 = min (offset2 + length, r2->offset + r2->length);
|
||||
|
||||
/* Make them relative to the respective start offsets, so we can
|
||||
compare them for equality. */
|
||||
l1 -= offset1;
|
||||
h1 -= offset1;
|
||||
|
||||
l2 -= offset2;
|
||||
h2 -= offset2;
|
||||
|
||||
/* Different availability, no match. */
|
||||
if (l1 != l2 || h1 != h2)
|
||||
return 0;
|
||||
|
||||
/* Compare the _available_ contents. */
|
||||
if (memcmp (val1->contents + org_offset1 + prev_avail,
|
||||
val2->contents + org_offset2 + prev_avail,
|
||||
l2 - prev_avail) != 0)
|
||||
return 0;
|
||||
|
||||
prev_avail += h1;
|
||||
length -= h1;
|
||||
offset1 += h1;
|
||||
offset2 += h1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Prototypes for local functions. */
|
||||
|
||||
static void show_values (char *, int);
|
||||
|
|
25
gdb/value.h
25
gdb/value.h
|
@ -374,6 +374,31 @@ extern int value_bytes_available (const struct value *value,
|
|||
extern void mark_value_bytes_unavailable (struct value *value,
|
||||
int offset, int length);
|
||||
|
||||
/* Compare LENGTH bytes of VAL1's contents starting at OFFSET1 with
|
||||
LENGTH bytes of VAL2's contents starting at OFFSET2. Returns true
|
||||
iff the set of available contents match. Unavailable contents
|
||||
compare equal with unavailable contents, and different with any
|
||||
available byte. For example, if 'x's represent an unavailable
|
||||
byte, and 'V' and 'Z' represent different available bytes, in a
|
||||
value with length 16:
|
||||
|
||||
offset: 0 4 8 12 16
|
||||
contents: xxxxVVVVxxxxVVZZ
|
||||
|
||||
then:
|
||||
|
||||
value_available_contents_eq(val, 0, val, 8, 6) => 1
|
||||
value_available_contents_eq(val, 0, val, 4, 4) => 1
|
||||
value_available_contents_eq(val, 0, val, 8, 8) => 0
|
||||
value_available_contents_eq(val, 4, val, 12, 2) => 1
|
||||
value_available_contents_eq(val, 4, val, 12, 4) => 0
|
||||
value_available_contents_eq(val, 3, val, 4, 4) => 0
|
||||
*/
|
||||
|
||||
extern int value_available_contents_eq (const struct value *val1, int offset1,
|
||||
const struct value *val2, int offset2,
|
||||
int length);
|
||||
|
||||
/* Read LENGTH bytes of memory starting at MEMADDR into BUFFER, which
|
||||
is (or will be copied to) VAL's contents buffer offset by
|
||||
EMBEDDED_OFFSET (that is, to &VAL->contents[EMBEDDED_OFFSET]).
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue