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>
|
2011-02-14 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
* target.c (target_read_live_memory): New function.
|
* 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,
|
||||||
(i * bitsize) % HOST_CHAR_BIT,
|
(i * bitsize) % HOST_CHAR_BIT,
|
||||||
bitsize, elttype);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -179,8 +179,11 @@ java_value_print (struct value *val, struct ui_file *stream,
|
||||||
set_value_lazy (next_v, 1);
|
set_value_lazy (next_v, 1);
|
||||||
set_value_offset (next_v, value_offset (next_v)
|
set_value_offset (next_v, value_offset (next_v)
|
||||||
+ TYPE_LENGTH (el_type));
|
+ TYPE_LENGTH (el_type));
|
||||||
if (memcmp (value_contents (v), value_contents (next_v),
|
value_fetch_lazy (next_v);
|
||||||
TYPE_LENGTH (el_type)) != 0)
|
if (!(value_available_contents_eq
|
||||||
|
(v, value_embedded_offset (v),
|
||||||
|
next_v, value_embedded_offset (next_v),
|
||||||
|
TYPE_LENGTH (el_type))))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1242,9 +1242,11 @@ val_print_array_elements (struct type *type,
|
||||||
rep1 = i + 1;
|
rep1 = i + 1;
|
||||||
reps = 1;
|
reps = 1;
|
||||||
while (rep1 < len
|
while (rep1 < len
|
||||||
&& memcmp (valaddr + embedded_offset + i * eltlen,
|
&& value_available_contents_eq (val,
|
||||||
valaddr + embedded_offset + rep1 * eltlen,
|
embedded_offset + i * eltlen,
|
||||||
eltlen) == 0)
|
val,
|
||||||
|
embedded_offset + rep1 * eltlen,
|
||||||
|
eltlen))
|
||||||
{
|
{
|
||||||
++reps;
|
++reps;
|
||||||
++rep1;
|
++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. */
|
/* Prototypes for local functions. */
|
||||||
|
|
||||||
static void show_values (char *, int);
|
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,
|
extern void mark_value_bytes_unavailable (struct value *value,
|
||||||
int offset, int length);
|
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
|
/* Read LENGTH bytes of memory starting at MEMADDR into BUFFER, which
|
||||||
is (or will be copied to) VAL's contents buffer offset by
|
is (or will be copied to) VAL's contents buffer offset by
|
||||||
EMBEDDED_OFFSET (that is, to &VAL->contents[EMBEDDED_OFFSET]).
|
EMBEDDED_OFFSET (that is, to &VAL->contents[EMBEDDED_OFFSET]).
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue