mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-03 04:12:10 +08:00
Mark pieces of values as unavailable if the corresponding memory
is unavailable. gdb/ * valops.c: Include tracepoint.h. (value_fetch_lazy): Use read_value_memory. (read_value_memory): New. * value.h (read_value_memory): Declare. * dwarf2loc.c (read_pieced_value): Use read_value_memory. * exec.c (section_table_available_memory): New function. * exec.h (section_table_available_memory): Declare.
This commit is contained in:
parent
2a7498d819
commit
e6ca34fcfb
@ -1,3 +1,16 @@
|
|||||||
|
2011-02-14 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
|
Mark pieces of values as unavailable if the corresponding memory
|
||||||
|
is unavailable.
|
||||||
|
|
||||||
|
* valops.c: Include tracepoint.h.
|
||||||
|
(value_fetch_lazy): Use read_value_memory.
|
||||||
|
(read_value_memory): New.
|
||||||
|
* value.h (read_value_memory): Declare.
|
||||||
|
* dwarf2loc.c (read_pieced_value): Use read_value_memory.
|
||||||
|
* exec.c (section_table_available_memory): New function.
|
||||||
|
* exec.h (section_table_available_memory): Declare.
|
||||||
|
|
||||||
2011-02-14 Pedro Alves <pedro@codesourcery.com>
|
2011-02-14 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
* Makefile.in (SFILES): Add memrange.c.
|
* Makefile.in (SFILES): Add memrange.c.
|
||||||
|
@ -603,10 +603,10 @@ read_pieced_value (struct value *v)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DWARF_VALUE_MEMORY:
|
case DWARF_VALUE_MEMORY:
|
||||||
if (p->v.mem.in_stack_memory)
|
read_value_memory (v, offset,
|
||||||
read_stack (p->v.mem.addr + source_offset, buffer, this_size);
|
p->v.mem.in_stack_memory,
|
||||||
else
|
p->v.mem.addr + source_offset,
|
||||||
read_memory (p->v.mem.addr + source_offset, buffer, this_size);
|
buffer, this_size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DWARF_VALUE_STACK:
|
case DWARF_VALUE_STACK:
|
||||||
|
37
gdb/exec.c
37
gdb/exec.c
@ -572,6 +572,43 @@ map_vmap (bfd *abfd, bfd *arch)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VEC(mem_range_s) *
|
||||||
|
section_table_available_memory (VEC(mem_range_s) *memory,
|
||||||
|
CORE_ADDR memaddr, LONGEST len,
|
||||||
|
struct target_section *sections,
|
||||||
|
struct target_section *sections_end)
|
||||||
|
{
|
||||||
|
struct target_section *p;
|
||||||
|
ULONGEST memend = memaddr + len;
|
||||||
|
|
||||||
|
for (p = sections; p < sections_end; p++)
|
||||||
|
{
|
||||||
|
if ((bfd_get_section_flags (p->bfd, p->the_bfd_section)
|
||||||
|
& SEC_READONLY) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Copy the meta-data, adjusted. */
|
||||||
|
if (mem_ranges_overlap (p->addr, p->endaddr - p->addr, memaddr, len))
|
||||||
|
{
|
||||||
|
ULONGEST lo1, hi1, lo2, hi2;
|
||||||
|
struct mem_range *r;
|
||||||
|
|
||||||
|
lo1 = memaddr;
|
||||||
|
hi1 = memaddr + len;
|
||||||
|
|
||||||
|
lo2 = p->addr;
|
||||||
|
hi2 = p->endaddr;
|
||||||
|
|
||||||
|
r = VEC_safe_push (mem_range_s, memory, NULL);
|
||||||
|
|
||||||
|
r->start = max (lo1, lo2);
|
||||||
|
r->length = min (hi1, hi2) - r->start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return memory;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
|
section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
|
||||||
ULONGEST offset, LONGEST len,
|
ULONGEST offset, LONGEST len,
|
||||||
|
12
gdb/exec.h
12
gdb/exec.h
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "progspace.h"
|
#include "progspace.h"
|
||||||
|
#include "memrange.h"
|
||||||
|
|
||||||
struct target_section;
|
struct target_section;
|
||||||
struct target_ops;
|
struct target_ops;
|
||||||
@ -44,6 +45,17 @@ extern int build_section_table (struct bfd *, struct target_section **,
|
|||||||
|
|
||||||
extern int resize_section_table (struct target_section_table *, int);
|
extern int resize_section_table (struct target_section_table *, int);
|
||||||
|
|
||||||
|
/* Appends all read-only memory ranges found in the target section
|
||||||
|
table defined by SECTIONS and SECTIONS_END, starting at (and
|
||||||
|
intersected with) MEMADDR for LEN bytes. Returns the augmented
|
||||||
|
VEC. */
|
||||||
|
|
||||||
|
extern VEC(mem_range_s) *
|
||||||
|
section_table_available_memory (VEC(mem_range_s) *ranges,
|
||||||
|
CORE_ADDR memaddr, LONGEST len,
|
||||||
|
struct target_section *sections,
|
||||||
|
struct target_section *sections_end);
|
||||||
|
|
||||||
/* Read or write from mappable sections of BFD executable files.
|
/* Read or write from mappable sections of BFD executable files.
|
||||||
|
|
||||||
Request to transfer up to LEN 8-bit bytes of the target sections
|
Request to transfer up to LEN 8-bit bytes of the target sections
|
||||||
|
93
gdb/valops.c
93
gdb/valops.c
@ -38,7 +38,7 @@
|
|||||||
#include "cp-support.h"
|
#include "cp-support.h"
|
||||||
#include "dfp.h"
|
#include "dfp.h"
|
||||||
#include "user-regs.h"
|
#include "user-regs.h"
|
||||||
|
#include "tracepoint.h"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "gdb_string.h"
|
#include "gdb_string.h"
|
||||||
#include "gdb_assert.h"
|
#include "gdb_assert.h"
|
||||||
@ -1009,12 +1009,8 @@ value_fetch_lazy (struct value *val)
|
|||||||
int length = TYPE_LENGTH (check_typedef (value_enclosing_type (val)));
|
int length = TYPE_LENGTH (check_typedef (value_enclosing_type (val)));
|
||||||
|
|
||||||
if (length)
|
if (length)
|
||||||
{
|
read_value_memory (val, 0, value_stack (val),
|
||||||
if (value_stack (val))
|
addr, value_contents_all_raw (val), length);
|
||||||
read_stack (addr, value_contents_all_raw (val), length);
|
|
||||||
else
|
|
||||||
read_memory (addr, value_contents_all_raw (val), length);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (VALUE_LVAL (val) == lval_register)
|
else if (VALUE_LVAL (val) == lval_register)
|
||||||
{
|
{
|
||||||
@ -1113,6 +1109,89 @@ value_fetch_lazy (struct value *val)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
read_value_memory (struct value *val, int embedded_offset,
|
||||||
|
int stack, CORE_ADDR memaddr,
|
||||||
|
gdb_byte *buffer, size_t length)
|
||||||
|
{
|
||||||
|
if (length)
|
||||||
|
{
|
||||||
|
VEC(mem_range_s) *available_memory;
|
||||||
|
|
||||||
|
if (get_traceframe_number () < 0
|
||||||
|
|| !traceframe_available_memory (&available_memory, memaddr, length))
|
||||||
|
{
|
||||||
|
if (stack)
|
||||||
|
read_stack (memaddr, buffer, length);
|
||||||
|
else
|
||||||
|
read_memory (memaddr, buffer, length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct target_section_table *table;
|
||||||
|
struct cleanup *old_chain;
|
||||||
|
CORE_ADDR unavail;
|
||||||
|
mem_range_s *r;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Fallback to reading from read-only sections. */
|
||||||
|
table = target_get_section_table (&exec_ops);
|
||||||
|
available_memory =
|
||||||
|
section_table_available_memory (available_memory,
|
||||||
|
memaddr, length,
|
||||||
|
table->sections,
|
||||||
|
table->sections_end);
|
||||||
|
|
||||||
|
old_chain = make_cleanup (VEC_cleanup(mem_range_s),
|
||||||
|
&available_memory);
|
||||||
|
|
||||||
|
normalize_mem_ranges (available_memory);
|
||||||
|
|
||||||
|
/* Mark which bytes are unavailable, and read those which
|
||||||
|
are available. */
|
||||||
|
|
||||||
|
unavail = memaddr;
|
||||||
|
|
||||||
|
for (i = 0;
|
||||||
|
VEC_iterate (mem_range_s, available_memory, i, r);
|
||||||
|
i++)
|
||||||
|
{
|
||||||
|
if (mem_ranges_overlap (r->start, r->length,
|
||||||
|
memaddr, length))
|
||||||
|
{
|
||||||
|
CORE_ADDR lo1, hi1, lo2, hi2;
|
||||||
|
CORE_ADDR start, end;
|
||||||
|
|
||||||
|
/* Get the intersection window. */
|
||||||
|
lo1 = memaddr;
|
||||||
|
hi1 = memaddr + length;
|
||||||
|
lo2 = r->start;
|
||||||
|
hi2 = r->start + r->length;
|
||||||
|
start = max (lo1, lo2);
|
||||||
|
end = min (hi1, hi2);
|
||||||
|
|
||||||
|
gdb_assert (end - memaddr <= length);
|
||||||
|
|
||||||
|
if (start > unavail)
|
||||||
|
mark_value_bytes_unavailable (val,
|
||||||
|
(embedded_offset
|
||||||
|
+ unavail - memaddr),
|
||||||
|
start - unavail);
|
||||||
|
unavail = end;
|
||||||
|
|
||||||
|
read_memory (start, buffer + start - memaddr, end - start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unavail != memaddr + length)
|
||||||
|
mark_value_bytes_unavailable (val,
|
||||||
|
embedded_offset + unavail - memaddr,
|
||||||
|
(memaddr + length) - unavail);
|
||||||
|
|
||||||
|
do_cleanups (old_chain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Store the contents of FROMVAL into the location of TOVAL.
|
/* Store the contents of FROMVAL into the location of TOVAL.
|
||||||
Return a new value with the location of TOVAL and contents of FROMVAL. */
|
Return a new value with the location of TOVAL and contents of FROMVAL. */
|
||||||
|
11
gdb/value.h
11
gdb/value.h
@ -374,6 +374,17 @@ 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);
|
||||||
|
|
||||||
|
/* 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]).
|
||||||
|
Marks value contents ranges as unavailable if the corresponding
|
||||||
|
memory is likewise unavailable. STACK indicates whether the memory
|
||||||
|
is known to be stack memory. */
|
||||||
|
|
||||||
|
extern void read_value_memory (struct value *val, int offset,
|
||||||
|
int stack, CORE_ADDR memaddr,
|
||||||
|
gdb_byte *buffer, size_t length);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "symtab.h"
|
#include "symtab.h"
|
||||||
|
Loading…
Reference in New Issue
Block a user