mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 02:40:08 +00:00
parent
c6881a8126
commit
d77cb2b1fc
@ -193,6 +193,26 @@ if {![regexp {Genode::Lock::lock} $output] ||
|
||||
exit -1
|
||||
}
|
||||
|
||||
puts "\n"
|
||||
puts "----- test: memory map -----"
|
||||
puts ""
|
||||
|
||||
send "info mem\n"
|
||||
run_genode_until {\(gdb\)} 20 $gdb_id
|
||||
|
||||
if {![regexp {..*y.*0x0000000000004000 0x0000000000006000 rw nocache} $output] ||
|
||||
![regexp {..*y.*0x0000000000008000 0x0000000000010000 rw nocache} $output] ||
|
||||
![regexp {..*y.*0x0000000000010000 0x0000000000012000 rw nocache} $output] ||
|
||||
![regexp {..*y.*0x0000000000030000 0x00000000000..000 rw nocache} $output] ||
|
||||
![regexp {7.*y.*0x0000000001000000 0x000000000100.000 rw nocache} $output] ||
|
||||
![regexp {8.*y.*0x000000000100.000 0x000000000100.000 rw nocache} $output] ||
|
||||
![regexp {9.*y.*0x00000000400fb000 0x00000000400ff000 rw nocache} $output] ||
|
||||
![regexp {1..*y.*0x00000000401ef000 0x00000000401ff000 rw nocache} $output] ||
|
||||
![regexp {1..*y.*0x00000000402f.000 0x00000000402ff000 rw nocache} $output]} {
|
||||
puts stderr "*** Error: memory map is not as expected"
|
||||
exit -1
|
||||
}
|
||||
|
||||
puts "\n"
|
||||
puts "----- test: stack trace of second inferior -----"
|
||||
puts ""
|
||||
@ -217,4 +237,22 @@ if {![regexp {Genode::Signal_receiver::block_for_signal} $output] } {
|
||||
exit -1
|
||||
}
|
||||
|
||||
puts "\n"
|
||||
puts "----- test: memory map of second inferior -----"
|
||||
puts ""
|
||||
|
||||
send "info mem\n"
|
||||
run_genode_until {\(gdb\)} 20 $gdb_id
|
||||
|
||||
if {![regexp {..*y.*0x0000000000008000 0x0000000000010000 rw nocache} $output] ||
|
||||
![regexp {..*y.*0x0000000000010000 0x0000000000012000 rw nocache} $output] ||
|
||||
![regexp {..*y.*0x0000000000030000 0x00000000000..000 ro nocache} $output] ||
|
||||
![regexp {5.*y.*0x0000000001000000 0x000000000100.000 ro nocache} $output] ||
|
||||
![regexp {6.*y.*0x000000000100.000 0x000000000100.000 rw nocache} $output] ||
|
||||
![regexp {7.*y.*0x00000000400fb000 0x00000000400ff000 rw nocache} $output] ||
|
||||
![regexp {..*y.*0x00000000401ef000 0x00000000401ff000 rw nocache} $output]} {
|
||||
puts stderr "*** Error: memory map of second inferior is not as expected"
|
||||
exit -1
|
||||
}
|
||||
|
||||
puts ""
|
||||
|
@ -53,6 +53,78 @@ struct Monitor::Gdb::State : Noncopyable
|
||||
}
|
||||
};
|
||||
|
||||
struct Memory_map
|
||||
{
|
||||
char _buf[1024*16] { };
|
||||
size_t _len = 0;
|
||||
|
||||
Memory_map(Inferior_pd &inferior)
|
||||
{
|
||||
typedef String<16> Value;
|
||||
|
||||
Xml_generator xml(_buf, sizeof(_buf), "memory-map", [&] {
|
||||
|
||||
inferior._address_space.for_each_region(
|
||||
[&] (Monitored_region_map::Region const ®ion) {
|
||||
|
||||
if (region.cap == inferior._linker_area.dataspace()) {
|
||||
|
||||
inferior._linker_area.for_each_region(
|
||||
[&] (Monitored_region_map::Region const
|
||||
&linker_area_region) {
|
||||
xml.node("memory", [&] {
|
||||
xml.attribute("type",
|
||||
linker_area_region.writeable ?
|
||||
"ram" : "rom");
|
||||
xml.attribute("start",
|
||||
Value(Hex(region.addr +
|
||||
linker_area_region.addr)));
|
||||
xml.attribute("length",
|
||||
Value(Hex(linker_area_region.size)));
|
||||
});
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (region.cap == inferior._stack_area.dataspace()) {
|
||||
|
||||
inferior._stack_area.for_each_region(
|
||||
[&] (Monitored_region_map::Region const
|
||||
&stack_area_region) {
|
||||
xml.node("memory", [&] {
|
||||
xml.attribute("type",
|
||||
stack_area_region.writeable ?
|
||||
"ram" : "rom");
|
||||
xml.attribute("start",
|
||||
Value(Hex(region.addr +
|
||||
stack_area_region.addr)));
|
||||
xml.attribute("length",
|
||||
Value(Hex(stack_area_region.size)));
|
||||
});
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
xml.node("memory", [&] {
|
||||
xml.attribute("type", region.writeable ? "ram" : "rom");
|
||||
xml.attribute("start", Value(Hex(region.addr)));
|
||||
xml.attribute("length", Value(Hex(region.size)));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
_len = strlen(_buf);
|
||||
}
|
||||
|
||||
void with_bytes(auto const &fn) const
|
||||
{
|
||||
Const_byte_range_ptr const ptr { _buf, _len };
|
||||
fn(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
Memory_accessor &_memory_accessor;
|
||||
|
||||
struct Current : Noncopyable
|
||||
@ -239,6 +311,7 @@ struct qSupported : Command_with_separator
|
||||
print(out, "vContSupported+;");
|
||||
print(out, "qXfer:features:read+;"); /* XML target descriptions */
|
||||
print(out, "qXfer:threads:read+;");
|
||||
print(out, "qXfer:memory-map:read+;");
|
||||
print(out, "multiprocess+;");
|
||||
print(out, "QNonStop+;");
|
||||
print(out, "swbreak+;");
|
||||
@ -304,6 +377,15 @@ struct qXfer : Command_with_separator
|
||||
handled = true;
|
||||
});
|
||||
|
||||
with_skipped_prefix(args, "memory-map:read::", [&] (Const_byte_range_ptr const &args) {
|
||||
if (state.current_defined()) {
|
||||
State::Memory_map const memory_map(state._current->pd);
|
||||
memory_map.with_bytes([&] (Const_byte_range_ptr const &bytes) {
|
||||
_send_window(out, bytes, Window::from_args(args)); });
|
||||
}
|
||||
handled = true;
|
||||
});
|
||||
|
||||
if (!handled)
|
||||
warning("GDB ", name, " command unsupported: ", Cstring(args.start, args.num_bytes));
|
||||
}
|
||||
|
@ -28,15 +28,6 @@ struct Monitor::Inferior_pd : Monitored_pd_session
|
||||
{
|
||||
Inferiors::Element _inferiors_elem;
|
||||
|
||||
Monitored_region_map _address_space {
|
||||
_ep, _real.call<Pd_session::Rpc_address_space>(), "address space" };
|
||||
|
||||
Monitored_region_map _stack_area {
|
||||
_ep, _real.call<Pd_session::Rpc_stack_area>(), "stack area" };
|
||||
|
||||
Monitored_region_map _linker_area {
|
||||
_ep, _real.call<Pd_session::Rpc_linker_area>(), "linker area" };
|
||||
|
||||
Threads _threads { };
|
||||
|
||||
Threads::Id _last_thread_id { };
|
||||
@ -47,6 +38,16 @@ struct Monitor::Inferior_pd : Monitored_pd_session
|
||||
Allocator &_alloc; /* used for allocating 'Ram_ds' objects */
|
||||
Ram_allocator &_wx_ram; /* RAM used for writeable text segments */
|
||||
|
||||
Monitored_region_map _address_space {
|
||||
_ep, _real.call<Pd_session::Rpc_address_space>(), "address space",
|
||||
_alloc };
|
||||
|
||||
Monitored_region_map _stack_area {
|
||||
_ep, _real.call<Pd_session::Rpc_stack_area>(), "stack area", _alloc };
|
||||
|
||||
Monitored_region_map _linker_area {
|
||||
_ep, _real.call<Pd_session::Rpc_linker_area>(), "linker area", _alloc };
|
||||
|
||||
struct Policy
|
||||
{
|
||||
bool wait; /* wait for GDB continue command */
|
||||
|
@ -27,8 +27,6 @@ namespace Monitor { struct Monitored_region_map; }
|
||||
|
||||
struct Monitor::Monitored_region_map : Monitored_rpc_object<Region_map>
|
||||
{
|
||||
using Monitored_rpc_object::Monitored_rpc_object;
|
||||
|
||||
/* see the comment in base/include/region_map/client.h */
|
||||
Dataspace_capability _rm_ds_cap { };
|
||||
|
||||
@ -97,6 +95,40 @@ struct Monitor::Monitored_region_map : Monitored_rpc_object<Region_map>
|
||||
_writeable_text_segments.construct(alloc, ram, local_rm);
|
||||
}
|
||||
|
||||
struct Region : List<Region>::Element
|
||||
{
|
||||
Dataspace_capability cap;
|
||||
addr_t addr;
|
||||
size_t size;
|
||||
bool writeable;
|
||||
|
||||
Region(Dataspace_capability cap, addr_t addr, size_t size,
|
||||
bool writeable)
|
||||
: cap(cap), addr(addr), size(size), writeable(writeable) { }
|
||||
};
|
||||
|
||||
List<Region> _regions { };
|
||||
|
||||
void for_each_region(auto const &fn) const
|
||||
{
|
||||
for (Region const *region = _regions.first(); region; region = region->next())
|
||||
fn(*region);
|
||||
}
|
||||
|
||||
Allocator &_alloc;
|
||||
|
||||
Monitored_region_map(Entrypoint &ep, Capability<Region_map> real,
|
||||
Name const &name, Allocator &alloc)
|
||||
: Monitored_rpc_object(ep, real, name),
|
||||
_alloc(alloc) { }
|
||||
|
||||
~Monitored_region_map()
|
||||
{
|
||||
while (Region *region = _regions.first()) {
|
||||
_regions.remove(region);
|
||||
destroy(_alloc, region);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************
|
||||
** Region_map interface **
|
||||
@ -114,13 +146,35 @@ struct Monitor::Monitored_region_map : Monitored_rpc_object<Region_map>
|
||||
writeable = true;
|
||||
}
|
||||
|
||||
return _real.call<Rpc_attach>(ds, size, offset, use_local_addr, local_addr,
|
||||
executable, writeable);
|
||||
Local_addr attached_addr = _real.call<Rpc_attach>(ds, size, offset,
|
||||
use_local_addr,
|
||||
local_addr,
|
||||
executable,
|
||||
writeable);
|
||||
size_t region_size = size ? size :
|
||||
(Dataspace_client(ds).size() - offset);
|
||||
enum { PAGE_SIZE_LOG2 = 12 };
|
||||
region_size = align_addr(region_size, PAGE_SIZE_LOG2);
|
||||
|
||||
_regions.insert(new (_alloc) Region(ds, (addr_t)attached_addr,
|
||||
region_size, writeable));
|
||||
return attached_addr;
|
||||
}
|
||||
|
||||
void detach(Local_addr local_addr) override
|
||||
{
|
||||
_real.call<Rpc_detach>(local_addr);
|
||||
|
||||
addr_t addr = (addr_t)local_addr;
|
||||
|
||||
for (Region *region = _regions.first(); region; region = region->next()) {
|
||||
if ((addr >= region->addr) &&
|
||||
(addr <= (region->addr + region->size - 1))) {
|
||||
_regions.remove(region);
|
||||
destroy(_alloc, region);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fault_handler(Signal_context_capability) override
|
||||
|
Loading…
Reference in New Issue
Block a user