mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-22 06:57:51 +00:00
parent
537dde1f40
commit
7a0bcbbccb
1
repos/ports/lib/mk/spec/foc/gdbserver_platform.mk
Normal file
1
repos/ports/lib/mk/spec/foc/gdbserver_platform.mk
Normal file
@ -0,0 +1 @@
|
||||
LIBS += gdbserver_platform_foc
|
1
repos/ports/lib/mk/spec/nova/gdbserver_platform.mk
Normal file
1
repos/ports/lib/mk/spec/nova/gdbserver_platform.mk
Normal file
@ -0,0 +1 @@
|
||||
LIBS += gdbserver_platform_nova
|
@ -1,3 +0,0 @@
|
||||
SRC_CC = spec/nova_x86_32/low.cc native_cpu.cc
|
||||
|
||||
include $(REP_DIR)/lib/mk/spec/x86_32/gdbserver_platform.inc
|
@ -1,3 +0,0 @@
|
||||
SRC_CC = spec/nova_x86_64/low.cc native_cpu.cc
|
||||
|
||||
include $(REP_DIR)/lib/mk/spec/x86_64/gdbserver_platform.inc
|
@ -3,4 +3,4 @@ SRC_CC = spec/foc_x86_32/low.cc \
|
||||
|
||||
LIBS += syscall-foc
|
||||
|
||||
include $(REP_DIR)/lib/mk/spec/x86_32/gdbserver_platform.inc
|
||||
include $(REP_DIR)/lib/mk/spec/x86_32/gdbserver_platform_x86_32.inc
|
@ -0,0 +1,3 @@
|
||||
SRC_CC = spec/nova_x86_32/low.cc native_cpu.cc
|
||||
|
||||
include $(REP_DIR)/lib/mk/spec/x86_32/gdbserver_platform_x86_32.inc
|
@ -0,0 +1,3 @@
|
||||
SRC_CC = spec/nova_x86_64/low.cc native_cpu.cc
|
||||
|
||||
include $(REP_DIR)/lib/mk/spec/x86_64/gdbserver_platform_x86_64.inc
|
@ -149,7 +149,30 @@ run_genode_until {.*\[init -> gdb_monitor\].*} 30
|
||||
|
||||
puts "GDB monitor is up, starting GDB in a new terminal"
|
||||
|
||||
exec [terminal] -e "[gdb] bin/nitpicker -ex \"target remote localhost:$local_port\"" &
|
||||
source ${genode_dir}/repos/ports/run/gdb_monitor.inc
|
||||
|
||||
# GDB loads symbols from 'bin/ld.lib.so'
|
||||
if { [have_spec nova] } {
|
||||
exec ln -sf ld-nova.lib.so bin/ld.lib.so
|
||||
}
|
||||
if { [have_spec foc] } {
|
||||
exec ln -sf ld-foc.lib.so bin/ld.lib.so
|
||||
}
|
||||
|
||||
set gdb_target_binary "nitpicker"
|
||||
|
||||
# sequence of GDB commands to execute at startup
|
||||
set gdb_cmds ""
|
||||
append gdb_cmds "-ex \"target remote localhost:$local_port\" "
|
||||
|
||||
append gdb_cmds [gdb_initial_breakpoint_cmds $gdb_target_binary]
|
||||
|
||||
# ask the user for confirmations again
|
||||
append gdb_cmds {-ex "set interactive-mode auto" }
|
||||
|
||||
puts "command: [gdb] bin/ld.lib.so $gdb_cmds"
|
||||
|
||||
exec [terminal] -e "[gdb] bin/ld.lib.so $gdb_cmds" &
|
||||
|
||||
interact -i [output_spawn_id]
|
||||
|
||||
|
@ -4,14 +4,12 @@
|
||||
# \date 2013-09-04
|
||||
#
|
||||
|
||||
proc gdb_main_breakpoint_cmds { target_binary_name } {
|
||||
proc gdb_initial_breakpoint_cmds { target_binary_name } {
|
||||
|
||||
#
|
||||
# We set a break in the 'main()' function of a dynamically linked
|
||||
# application by using the following gdb command sequence. It's important that
|
||||
# the 'main()' breakpoint gets set before the 'sharedlibrary' command is
|
||||
# executed. Otherwise the breakpoint would get set in ld.lib.so's main()
|
||||
# function.
|
||||
# We set a break in the 'binary_ready_hook_for_gdb()' function in the
|
||||
# dynamic linker and load the symbols of the application by using the
|
||||
# following gdb command sequence.
|
||||
#
|
||||
|
||||
set gdb_cmds ""
|
||||
@ -31,20 +29,11 @@ proc gdb_main_breakpoint_cmds { target_binary_name } {
|
||||
# load the symbols of the test application
|
||||
append gdb_cmds "-ex \"file bin/$target_binary_name\" "
|
||||
|
||||
# set a breakpoint in the application's 'main()' function
|
||||
append gdb_cmds {-ex "b main" }
|
||||
|
||||
# set search path for "sharedlibrary" to bin
|
||||
append gdb_cmds {-ex "set solib-search-path bin" }
|
||||
|
||||
# load the symbols of loaded shared libraries
|
||||
append gdb_cmds {-ex "sharedlibrary" }
|
||||
|
||||
# continue execution until the breakpoint triggers
|
||||
append gdb_cmds {-ex "c" }
|
||||
|
||||
# delete the 'main()' breakpoint
|
||||
append gdb_cmds {-ex "delete 2" }
|
||||
|
||||
return $gdb_cmds
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ install_config $config
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
core init timer
|
||||
ld.lib.so libc.lib.so libc_pipe.lib.so libc_terminal.lib.so
|
||||
ld.lib.so libc.lib.so libm.lib.so libc_pipe.lib.so libc_terminal.lib.so
|
||||
uart_drv
|
||||
gdb_monitor test-gdb_monitor
|
||||
}
|
||||
@ -120,12 +120,20 @@ puts "GDB monitor is up, starting GDB"
|
||||
|
||||
source ${genode_dir}/repos/ports/run/gdb_monitor.inc
|
||||
|
||||
# GDB loads symbols from 'bin/ld.lib.so'
|
||||
if { [have_spec nova] } {
|
||||
exec ln -sf ld-nova.lib.so bin/ld.lib.so
|
||||
}
|
||||
if { [have_spec foc] } {
|
||||
exec ln -sf ld-foc.lib.so bin/ld.lib.so
|
||||
}
|
||||
|
||||
set gdb_target_binary "test-gdb_monitor"
|
||||
|
||||
# sequence of GDB commands to execute at startup
|
||||
set gdb_cmds ""
|
||||
append gdb_cmds {-ex "target remote localhost:$local_port" }
|
||||
append gdb_cmds [gdb_main_breakpoint_cmds $gdb_target_binary]
|
||||
append gdb_cmds [gdb_initial_breakpoint_cmds $gdb_target_binary]
|
||||
|
||||
# run GDB and redirect stderr to stdio to get the relevant output into the expect buffer
|
||||
eval spawn [gdb] bin/ld.lib.so -n $gdb_cmds 2&>1
|
||||
@ -137,11 +145,19 @@ puts ""
|
||||
|
||||
run_genode_until {\(gdb\)} 60 $gdb_id
|
||||
|
||||
send "b main\n"
|
||||
run_genode_until {\(gdb\)} 20 $gdb_id
|
||||
send "c\n"
|
||||
run_genode_until {\(gdb\)} 20 $gdb_id
|
||||
|
||||
if {![regexp {Breakpoint 2, main ()} $output]} {
|
||||
puts stderr "*** Error: Breakpoint in main() did not trigger"
|
||||
exit -1
|
||||
}
|
||||
|
||||
send "delete 2\n"
|
||||
run_genode_until {\(gdb\)} 20 $gdb_id
|
||||
|
||||
puts "\n"
|
||||
puts "----- test: breakpoint in shared library -----"
|
||||
puts ""
|
||||
|
@ -77,7 +77,7 @@ install_config $config
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
core init timer
|
||||
ld.lib.so libc.lib.so libc_pipe.lib.so libc_terminal.lib.so
|
||||
ld.lib.so libc.lib.so libm.lib.so libc_pipe.lib.so libc_terminal.lib.so
|
||||
uart_drv
|
||||
gdb_monitor test-gdb_monitor
|
||||
}
|
||||
@ -106,18 +106,26 @@ puts "GDB monitor is up, starting GDB in a new terminal"
|
||||
|
||||
source ${genode_dir}/repos/ports/run/gdb_monitor.inc
|
||||
|
||||
# GDB loads symbols from 'bin/ld.lib.so'
|
||||
if { [have_spec nova] } {
|
||||
exec ln -sf ld-nova.lib.so bin/ld.lib.so
|
||||
}
|
||||
if { [have_spec foc] } {
|
||||
exec ln -sf ld-foc.lib.so bin/ld.lib.so
|
||||
}
|
||||
|
||||
set gdb_target_binary "test-gdb_monitor"
|
||||
|
||||
# sequence of GDB commands to execute at startup
|
||||
set gdb_cmds ""
|
||||
append gdb_cmds "-ex \"target remote localhost:$local_port\" "
|
||||
|
||||
append gdb_cmds [gdb_main_breakpoint_cmds $gdb_target_binary]
|
||||
append gdb_cmds [gdb_initial_breakpoint_cmds $gdb_target_binary]
|
||||
|
||||
# ask the user for confirmations again
|
||||
append gdb_cmds {-ex "set interactive-mode auto" }
|
||||
|
||||
puts "command: [gdb] bin/$gdb_target_binary $gdb_cmds"
|
||||
puts "command: [gdb] bin/ld.lib.so $gdb_cmds"
|
||||
|
||||
exec [terminal] -e "[gdb] bin/ld.lib.so $gdb_cmds" &
|
||||
|
||||
|
@ -53,10 +53,16 @@ set config {
|
||||
<config>
|
||||
<target name="test-gdb_monitor_target_config">
|
||||
<config>
|
||||
<libc stdout="/dev/log" stderr="/dev/log">
|
||||
<vfs> <dir name="dev"> <log/> </dir> </vfs>
|
||||
</libc>
|
||||
<test_config_subnode/>
|
||||
</config>
|
||||
</target>
|
||||
<preserve name="RAM" quantum="3M"/>
|
||||
<libc stdout="/dev/log" stderr="/dev/log">
|
||||
<vfs> <dir name="dev"> <log/> </dir> </vfs>
|
||||
</libc>
|
||||
</config>
|
||||
</start>
|
||||
</config>
|
||||
@ -98,15 +104,29 @@ run_genode_until {.*Remote debugging using /dev/terminal.*} 30
|
||||
|
||||
puts "GDB monitor is up, starting GDB in a new terminal"
|
||||
|
||||
source ${genode_dir}/repos/ports/run/gdb_monitor.inc
|
||||
|
||||
# GDB loads symbols from 'bin/ld.lib.so'
|
||||
if { [have_spec nova] } {
|
||||
exec ln -sf ld-nova.lib.so bin/ld.lib.so
|
||||
}
|
||||
if { [have_spec foc] } {
|
||||
exec ln -sf ld-foc.lib.so bin/ld.lib.so
|
||||
}
|
||||
|
||||
set gdb_target_binary "test-gdb_monitor_target_config"
|
||||
|
||||
# sequence of GDB commands to execute at startup
|
||||
set gdb_cmds ""
|
||||
append gdb_cmds "-ex \"target remote localhost:$local_port\" "
|
||||
|
||||
append gdb_cmds [gdb_initial_breakpoint_cmds $gdb_target_binary]
|
||||
|
||||
# continue execution
|
||||
append gdb_cmds {-ex "c" }
|
||||
|
||||
exec [terminal] -e "[gdb] bin/test-gdb_monitor_target_config $gdb_cmds" &
|
||||
exec [terminal] -e "[gdb] bin/ld.lib.so $gdb_cmds" &
|
||||
|
||||
interact
|
||||
interact -i [output_spawn_id]
|
||||
|
||||
# vi: set ft=tcl :
|
||||
|
@ -1,5 +1,5 @@
|
||||
if {![have_spec foc] && ![have_spec nova]} {
|
||||
puts "\nThe Noux GDB scenario is supported on NOVA and Fiasco.OC only\n"
|
||||
if {!([have_spec nova] || ([have_spec foc] && [have_spec 32bit]))} {
|
||||
puts "\nThe Noux GDB scenario is only supported for NOVA or 32-bit Fiasco.OC\n"
|
||||
exit 0
|
||||
}
|
||||
|
||||
@ -26,7 +26,10 @@ set build_components {
|
||||
app/gdb_monitor
|
||||
}
|
||||
|
||||
lappend_if [have_spec gpio] build_components drivers/gpio
|
||||
lappend_if [have_spec gpio] build_components drivers/gpio
|
||||
|
||||
lappend_if [have_spec nova] build_components lib/ld/nova
|
||||
lappend_if [have_spec foc] build_components lib/ld/foc
|
||||
|
||||
lappend build_components noux-pkg/[noux_gdb_pkg_name]
|
||||
|
||||
@ -39,11 +42,20 @@ append_platform_drv_build_components
|
||||
|
||||
build $build_components
|
||||
|
||||
# GDB loads symbols from 'bin/ld.lib.so'
|
||||
if { [have_spec nova] } {
|
||||
exec ln -sf ld-nova.lib.so bin/ld.lib.so
|
||||
}
|
||||
if { [have_spec foc] } {
|
||||
exec ln -sf ld-foc.lib.so bin/ld.lib.so
|
||||
}
|
||||
|
||||
# names of the binaries needed for the GDB monitor test
|
||||
set gdb_target_binaries {
|
||||
test-gdb_monitor
|
||||
ld.lib.so
|
||||
libc.lib.so
|
||||
libm.lib.so
|
||||
}
|
||||
lappend gdb_target_binaries ${gdb_target_binary_name}
|
||||
|
||||
|
@ -1,162 +0,0 @@
|
||||
if {![have_spec foc] || ![have_spec 32bit]} {
|
||||
puts "\nThe Noux GDB scenario is supported on 32-bit Fiasco.OC only\n"
|
||||
exit 0
|
||||
}
|
||||
|
||||
source ${genode_dir}/repos/ports/run/noux_gdb.inc
|
||||
|
||||
#
|
||||
# Uncomment the following line when working on the GDB source code. Otherwise,
|
||||
# the package may get recompiled, yet it does not get reinstalled into 'bin/'.
|
||||
#
|
||||
#exec rm -rf noux-pkg/[noux_gdb_pkg_name]/ bin/[noux_gdb_pkg_name]/
|
||||
|
||||
set build_components {
|
||||
core init drivers/timer noux lib/libc_noux
|
||||
drivers/uart
|
||||
server/terminal_mux server/terminal_crosslink
|
||||
server/terminal_log
|
||||
app/cli_monitor
|
||||
app/gdb_monitor
|
||||
}
|
||||
lappend build_components noux-pkg/[noux_gdb_pkg_name]
|
||||
|
||||
lappend build_components test/gdb_monitor
|
||||
set gdb_target_binary_name test-gdb_monitor
|
||||
|
||||
build $build_components
|
||||
|
||||
# names of the binaries needed for the GDB monitor test
|
||||
set gdb_target_binaries {
|
||||
ld.lib.so
|
||||
libc.lib.so
|
||||
}
|
||||
lappend gdb_target_binaries ${gdb_target_binary_name}
|
||||
|
||||
create_gdb_tar
|
||||
create_binary_and_source_tars "gdb_target" ${gdb_target_binaries}
|
||||
|
||||
create_boot_directory
|
||||
|
||||
append config {
|
||||
<config verbose="yes">
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="LOG"/>
|
||||
<service name="RAM"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="PD"/>
|
||||
<service name="IRQ"/>
|
||||
<service name="IO_PORT"/>
|
||||
<service name="IO_MEM"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Timer"/></provides>
|
||||
<route> <any-service> <parent/> </any-service> </route>
|
||||
</start>
|
||||
|
||||
<start name="uart_drv">}
|
||||
|
||||
# use kernel debugger as UART on Fiasco.OC
|
||||
append_if [have_spec foc] config {
|
||||
<binary name="kdb_uart_drv"/>}
|
||||
|
||||
append config {
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides>
|
||||
<service name="Uart"/>
|
||||
<service name="Terminal"/>
|
||||
</provides>
|
||||
<config> }
|
||||
|
||||
# on Fiasco.OC the kdb_uart_drv is always UART 0
|
||||
append_if [have_spec foc] config {
|
||||
<policy label_prefix="terminal_mux" uart="0" detect_size="yes"/> }
|
||||
|
||||
# on all other kernels, direct terminal_mux to UART 1 (Qemu stdio, see below)
|
||||
append_if [expr ![have_spec foc]] config {
|
||||
<policy label_prefix="terminal_mux" uart="1" detect_size="yes"/> }
|
||||
|
||||
append config {
|
||||
</config>
|
||||
<route> <any-service> <parent/> <any-child/> </any-service> </route>
|
||||
</start>
|
||||
<start name="terminal_mux">
|
||||
<resource name="RAM" quantum="3M"/>
|
||||
<provides><service name="Terminal"/></provides>
|
||||
<route>
|
||||
<service name="Terminal"><child name="uart_drv"/></service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
<config>
|
||||
<keyboard layout="de"/>
|
||||
</config>
|
||||
</start>
|
||||
<start name="terminal_log">
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<provides>
|
||||
<service name="LOG"/>
|
||||
</provides>
|
||||
<route>
|
||||
<any-service><child name="terminal_mux"/> <any-child/> <parent/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
<start name="cli_monitor">
|
||||
<resource name="RAM" quantum="3G"/>
|
||||
<config>
|
||||
<subsystem name="gdb_test" help="GDB test application"> }
|
||||
append config "
|
||||
<binary name=\"${gdb_target_binary_name}\"/> "
|
||||
append config {
|
||||
<resource name="RAM" quantum="50M"/>
|
||||
</subsystem>
|
||||
</config>
|
||||
<route>
|
||||
<service name="LOG"><child name="terminal_log"/></service>
|
||||
<service name="Terminal"><child name="terminal_mux"/></service>
|
||||
<any-service><parent/><any-child/></any-service>
|
||||
</route>
|
||||
</start>
|
||||
</config>
|
||||
}
|
||||
|
||||
install_config $config
|
||||
|
||||
|
||||
#
|
||||
# Boot modules
|
||||
#
|
||||
|
||||
exec cp ${genode_dir}/repos/os/src/app/cli_monitor/gdb_command_config bin
|
||||
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
core init timer ld.lib.so noux terminal_mux terminal_crosslink
|
||||
libc.lib.so libm.lib.so libc_noux.lib.so ncurses.lib.so expat.lib.so
|
||||
libc_pipe.lib.so libc_terminal.lib.so
|
||||
cli_monitor gdb_monitor terminal_log gdb.tar
|
||||
gdb_command_config
|
||||
gdb_target.tar
|
||||
gdb_target-src.tar
|
||||
}
|
||||
lappend boot_modules ${gdb_target_binary_name}
|
||||
|
||||
# platform-specific modules
|
||||
lappend_if [expr ![have_spec foc]] boot_modules uart_drv
|
||||
lappend_if [have_spec foc] boot_modules kdb_uart_drv
|
||||
|
||||
set fiasco_serial_esc_arg ""
|
||||
|
||||
build_boot_image $boot_modules
|
||||
|
||||
append qemu_args " -nographic "
|
||||
|
||||
run_genode_until forever
|
||||
|
||||
exec rm bin/gdb.tar
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2016 Genode Labs GmbH
|
||||
* Copyright (C) 2009-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -14,9 +14,7 @@
|
||||
#ifndef _APP_CHILD_H_
|
||||
#define _APP_CHILD_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/child.h>
|
||||
#include <base/service.h>
|
||||
|
||||
@ -25,37 +23,43 @@
|
||||
|
||||
#include <util/arg_string.h>
|
||||
|
||||
/* GDB monitor includes */
|
||||
#include "genode_child_resources.h"
|
||||
#include "cpu_session_component.h"
|
||||
#include "pd_session_component.h"
|
||||
#include "rom.h"
|
||||
|
||||
namespace Gdb_monitor {
|
||||
using namespace Genode;
|
||||
|
||||
namespace Gdb_monitor { class App_child; }
|
||||
class App_child;
|
||||
}
|
||||
|
||||
class Gdb_monitor::App_child : public Child_policy
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Genode::Registered<Genode::Parent_service> Parent_service;
|
||||
typedef Genode::Registry<Parent_service> Parent_services;
|
||||
typedef Registered<Genode::Parent_service> Parent_service;
|
||||
typedef Registry<Parent_service> Parent_services;
|
||||
|
||||
private:
|
||||
|
||||
enum { STACK_SIZE = 4*1024*sizeof(long) };
|
||||
|
||||
Genode::Env &_env;
|
||||
Env &_env;
|
||||
|
||||
Genode::Ram_session_capability _ref_ram_cap { _env.ram_session_cap() };
|
||||
Genode::Ram_session_client _ref_ram { _ref_ram_cap };
|
||||
Allocator &_alloc;
|
||||
|
||||
Ram_session_capability _ref_ram_cap { _env.ram_session_cap() };
|
||||
Ram_session_client _ref_ram { _ref_ram_cap };
|
||||
|
||||
const char *_unique_name;
|
||||
|
||||
Genode::Dataspace_capability _elf_ds;
|
||||
Dataspace_capability _elf_ds;
|
||||
|
||||
Genode::Region_map &_rm;
|
||||
Region_map &_rm;
|
||||
|
||||
Genode::size_t _ram_quota;
|
||||
size_t _ram_quota;
|
||||
|
||||
Rpc_entrypoint _entrypoint;
|
||||
|
||||
@ -71,7 +75,7 @@ class Gdb_monitor::App_child : public Child_policy
|
||||
|
||||
Dataspace_pool _managed_ds_map;
|
||||
|
||||
Pd_session_component _pd {_unique_name, _entrypoint, _managed_ds_map};
|
||||
Pd_session_component _pd { _entrypoint, _env, _alloc, _unique_name, _managed_ds_map };
|
||||
Pd_service::Single_session_factory _pd_factory { _pd };
|
||||
Pd_service _pd_service { _pd_factory };
|
||||
|
||||
@ -83,156 +87,16 @@ class Gdb_monitor::App_child : public Child_policy
|
||||
|
||||
Child *_child;
|
||||
|
||||
/* FIXME */
|
||||
#if 0
|
||||
/**
|
||||
* Proxy for a service provided by the child
|
||||
*/
|
||||
class Child_service_root : public Genode::Rpc_object<Genode::Root>
|
||||
{
|
||||
private:
|
||||
|
||||
/**
|
||||
* Root interface of the real service, provided by the child
|
||||
*/
|
||||
Genode::Root_client _child_root;
|
||||
|
||||
/**
|
||||
* Child's RAM session used for quota transfers
|
||||
*/
|
||||
Genode::Ram_session_capability _child_ram;
|
||||
|
||||
struct Child_session;
|
||||
typedef Genode::Object_pool<Child_session> Session_pool;
|
||||
|
||||
/**
|
||||
* Per-session meta data
|
||||
*
|
||||
* For each session, we need to keep track of the quota
|
||||
* attached to it - in order to revert the quota donation
|
||||
* when the session gets closed.
|
||||
*/
|
||||
struct Child_session : public Session_pool::Entry
|
||||
{
|
||||
Genode::size_t ram_quota;
|
||||
|
||||
Child_session(Genode::Session_capability cap,
|
||||
Genode::size_t ram_quota)
|
||||
: Session_pool::Entry(cap), ram_quota(ram_quota) { }
|
||||
};
|
||||
|
||||
/**
|
||||
* Data base containing per-session meta data
|
||||
*/
|
||||
Session_pool _sessions;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
|
||||
Child_service_root(Genode::Ram_session_capability child_ram,
|
||||
Genode::Root_capability child_root)
|
||||
: _child_root(child_root), _child_ram(child_ram)
|
||||
{ }
|
||||
|
||||
/********************
|
||||
** Root interface **
|
||||
********************/
|
||||
|
||||
Session_capability session(Session_args const &args,
|
||||
Affinity const &affinity)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
Genode::size_t ram_quota =
|
||||
Arg_string::find_arg(args.string(),
|
||||
"ram_quota").ulong_value(0);
|
||||
|
||||
/* forward session quota to child */
|
||||
env()->ram_session()->transfer_quota(_child_ram, ram_quota);
|
||||
|
||||
Session_capability cap = _child_root.session(args, affinity);
|
||||
|
||||
/*
|
||||
* Keep information about donated quota in '_sessions'
|
||||
* data base.
|
||||
*/
|
||||
_sessions.insert(new (env()->heap())
|
||||
Child_session(cap, ram_quota));
|
||||
return cap;
|
||||
}
|
||||
|
||||
void upgrade(Session_capability session_cap,
|
||||
Upgrade_args const &args)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
auto lambda = [&] (Child_session *session) {
|
||||
if (!session) {
|
||||
error("attempt to upgrade unknown session");
|
||||
return;
|
||||
}
|
||||
|
||||
Genode::size_t ram_quota =
|
||||
Arg_string::find_arg(args.string(),
|
||||
"ram_quota").ulong_value(0);
|
||||
|
||||
/* forward session quota to child */
|
||||
env()->ram_session()->transfer_quota(_child_ram, ram_quota);
|
||||
|
||||
session->ram_quota += ram_quota;
|
||||
|
||||
/* inform child about quota upgrade */
|
||||
_child_root.upgrade(session_cap, args);
|
||||
};
|
||||
|
||||
_sessions.apply(session_cap, lambda);
|
||||
}
|
||||
|
||||
void close(Session_capability session_cap)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
Child_session *session;
|
||||
|
||||
auto lambda = [&] (Child_session *s) {
|
||||
session = s;
|
||||
|
||||
if (!session) {
|
||||
error("attempt to close unknown session");
|
||||
return;
|
||||
}
|
||||
_sessions.remove(session);
|
||||
};
|
||||
_sessions.apply(session_cap, lambda);
|
||||
|
||||
Genode::size_t ram_quota = session->ram_quota;
|
||||
destroy(env()->heap(), session);
|
||||
|
||||
_child_root.close(session_cap);
|
||||
|
||||
/*
|
||||
* The child is expected to free enough quota to revert
|
||||
* the quota donation.
|
||||
*/
|
||||
|
||||
Ram_session_client child_ram(_child_ram);
|
||||
child_ram.transfer_quota(env()->ram_session_cap(), ram_quota);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
void _dispatch_unresolved_page_fault(unsigned)
|
||||
{
|
||||
_genode_child_resources.cpu_session_component()->handle_unresolved_page_fault();
|
||||
_genode_child_resources.cpu_session_component().handle_unresolved_page_fault();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static Genode::Service *_find_service(Genode::Registry<T> &services,
|
||||
Genode::Service::Name const &name)
|
||||
static Service *_find_service(Registry<T> &services,
|
||||
Service::Name const &name)
|
||||
{
|
||||
Genode::Service *service = nullptr;
|
||||
Service *service = nullptr;
|
||||
services.for_each([&] (T &s) {
|
||||
if (!service && (s.name() == name))
|
||||
service = &s; });
|
||||
@ -244,27 +108,27 @@ class Gdb_monitor::App_child : public Child_policy
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
App_child(Genode::Env &env,
|
||||
const char *unique_name,
|
||||
Genode::Pd_session &pd,
|
||||
Genode::Region_map &rm,
|
||||
Genode::size_t ram_quota,
|
||||
Signal_receiver *signal_receiver,
|
||||
Xml_node target_node)
|
||||
App_child(Env &env,
|
||||
Allocator &alloc,
|
||||
char const *unique_name,
|
||||
size_t ram_quota,
|
||||
Signal_receiver &signal_receiver,
|
||||
Xml_node target_node)
|
||||
:
|
||||
_env(env),
|
||||
_alloc(alloc),
|
||||
_unique_name(unique_name),
|
||||
_rm(rm),
|
||||
_rm(_env.rm()),
|
||||
_ram_quota(ram_quota),
|
||||
_entrypoint(&pd, STACK_SIZE, "GDB monitor entrypoint"),
|
||||
_child_config(env.ram(), rm, target_node),
|
||||
_entrypoint(&_env.pd(), STACK_SIZE, "GDB monitor entrypoint"),
|
||||
_child_config(env.ram(), _rm, target_node),
|
||||
_config_policy("config", _child_config.dataspace(), &_entrypoint),
|
||||
_unresolved_page_fault_dispatcher(*signal_receiver,
|
||||
_unresolved_page_fault_dispatcher(signal_receiver,
|
||||
*this,
|
||||
&App_child::_dispatch_unresolved_page_fault),
|
||||
_cpu_factory(_env, _entrypoint, Genode::env()->heap(), _pd.core_pd_cap(),
|
||||
_cpu_factory(_env, _entrypoint, _alloc, _pd.core_pd_cap(),
|
||||
signal_receiver, &_genode_child_resources),
|
||||
_rom_factory(env, _entrypoint)
|
||||
_rom_factory(env, _entrypoint, _alloc)
|
||||
{
|
||||
_genode_child_resources.region_map_component(&_pd.region_map());
|
||||
_pd.region_map().fault_handler(_unresolved_page_fault_dispatcher);
|
||||
@ -272,7 +136,7 @@ class Gdb_monitor::App_child : public Child_policy
|
||||
|
||||
~App_child()
|
||||
{
|
||||
destroy(env()->heap(), _child);
|
||||
destroy(_alloc, _child);
|
||||
}
|
||||
|
||||
Genode_child_resources *genode_child_resources()
|
||||
@ -282,7 +146,7 @@ class Gdb_monitor::App_child : public Child_policy
|
||||
|
||||
void start()
|
||||
{
|
||||
_child = new (env()->heap()) Child(_rm, _entrypoint, *this);
|
||||
_child = new (_alloc) Child(_rm, _entrypoint, *this);
|
||||
}
|
||||
|
||||
/****************************
|
||||
@ -291,19 +155,19 @@ class Gdb_monitor::App_child : public Child_policy
|
||||
|
||||
Name name() const override { return _unique_name; }
|
||||
|
||||
Genode::Ram_session &ref_ram() override { return _ref_ram; }
|
||||
Ram_session &ref_ram() override { return _ref_ram; }
|
||||
|
||||
Genode::Ram_session_capability ref_ram_cap() const override { return _ref_ram_cap; }
|
||||
Ram_session_capability ref_ram_cap() const override { return _ref_ram_cap; }
|
||||
|
||||
void init(Genode::Ram_session &session,
|
||||
Genode::Ram_session_capability cap) override
|
||||
void init(Ram_session &session,
|
||||
Ram_session_capability cap) override
|
||||
{
|
||||
session.ref_account(_ref_ram_cap);
|
||||
_ref_ram.transfer_quota(cap, _ram_quota);
|
||||
}
|
||||
|
||||
Service &resolve_session_request(Genode::Service::Name const &service_name,
|
||||
Genode::Session_state::Args const &args) override
|
||||
Service &resolve_session_request(Service::Name const &service_name,
|
||||
Session_state::Args const &args) override
|
||||
{
|
||||
Service *service = nullptr;
|
||||
|
||||
@ -322,7 +186,7 @@ class Gdb_monitor::App_child : public Child_policy
|
||||
|
||||
service = _find_service(_parent_services, service_name);
|
||||
if (!service)
|
||||
service = new (env()->heap()) Parent_service(_parent_services, _env, service_name);
|
||||
service = new (_alloc) Parent_service(_parent_services, _env, service_name);
|
||||
|
||||
if (!service)
|
||||
throw Parent::Service_denied();
|
||||
@ -334,15 +198,7 @@ class Gdb_monitor::App_child : public Child_policy
|
||||
// to the child
|
||||
void announce_service(Service::Name const &name) override
|
||||
{
|
||||
/* FIXME */
|
||||
#if 0
|
||||
/* create and announce proxy for the child's root interface */
|
||||
Child_service_root *r = new (alloc)
|
||||
Child_service_root(_ram_session, root);
|
||||
Genode::env()->parent()->announce(name, _root_ep->manage(r));
|
||||
#else
|
||||
Genode::warning(__PRETTY_FUNCTION__, ": not implemented");
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2016 Genode Labs GmbH
|
||||
* Copyright (C) 2011-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -21,6 +21,9 @@
|
||||
/* GDB monitor includes */
|
||||
#include "cpu_thread_component.h"
|
||||
|
||||
/* libc includes */
|
||||
#include <sys/signal.h>
|
||||
|
||||
/* genode-low.cc */
|
||||
extern void genode_remove_thread(unsigned long lwpid);
|
||||
|
||||
@ -40,7 +43,7 @@ Rpc_entrypoint &Cpu_session_component::thread_ep()
|
||||
}
|
||||
|
||||
|
||||
Signal_receiver *Cpu_session_component::exception_signal_receiver()
|
||||
Signal_receiver &Cpu_session_component::exception_signal_receiver()
|
||||
{
|
||||
return _exception_signal_receiver;
|
||||
}
|
||||
@ -299,11 +302,11 @@ Capability<Cpu_session::Native_cpu> Cpu_session_component::native_cpu()
|
||||
}
|
||||
|
||||
|
||||
Cpu_session_component::Cpu_session_component(Genode::Env &env,
|
||||
Cpu_session_component::Cpu_session_component(Env &env,
|
||||
Rpc_entrypoint &ep,
|
||||
Allocator *md_alloc,
|
||||
Allocator &md_alloc,
|
||||
Pd_session_capability core_pd,
|
||||
Signal_receiver *exception_signal_receiver,
|
||||
Signal_receiver &exception_signal_receiver,
|
||||
const char *args,
|
||||
Affinity const &affinity)
|
||||
: _env(env),
|
||||
@ -335,7 +338,7 @@ Cpu_session_component::~Cpu_session_component()
|
||||
int Cpu_session_component::ref_account(Cpu_session_capability) { return -1; }
|
||||
|
||||
|
||||
int Cpu_session_component::transfer_quota(Cpu_session_capability, Genode::size_t) { return -1; }
|
||||
int Cpu_session_component::transfer_quota(Cpu_session_capability, size_t) { return -1; }
|
||||
|
||||
|
||||
Cpu_session::Quota Cpu_session_component::quota() { return Quota(); }
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2016 Genode Labs GmbH
|
||||
* Copyright (C) 2006-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -31,13 +31,13 @@
|
||||
|
||||
namespace Gdb_monitor
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
class Cpu_session_component;
|
||||
class Cpu_thread_component;
|
||||
class Local_cpu_factory;
|
||||
|
||||
typedef Genode::Local_service<Cpu_session_component> Cpu_service;
|
||||
|
||||
using namespace Genode;
|
||||
typedef Local_service<Cpu_session_component> Cpu_service;
|
||||
}
|
||||
|
||||
|
||||
@ -46,29 +46,29 @@ class Gdb_monitor::Cpu_session_component : public Rpc_object<Cpu_session>
|
||||
|
||||
private:
|
||||
|
||||
Genode::Env &_env;
|
||||
Env &_env;
|
||||
|
||||
Genode::Parent::Client _parent_client;
|
||||
Parent::Client _parent_client;
|
||||
|
||||
Id_space<Parent::Client>::Element const _id_space_element
|
||||
Id_space<Parent::Client>::Element const _id_space_element
|
||||
{ _parent_client, _env.id_space() };
|
||||
|
||||
Rpc_entrypoint &_ep;
|
||||
Allocator *_md_alloc;
|
||||
Rpc_entrypoint &_ep;
|
||||
Allocator &_md_alloc;
|
||||
|
||||
Pd_session_capability _core_pd;
|
||||
Pd_session_capability _core_pd;
|
||||
|
||||
Cpu_session_client _parent_cpu_session;
|
||||
Signal_receiver *_exception_signal_receiver;
|
||||
Cpu_session_client _parent_cpu_session;
|
||||
Signal_receiver &_exception_signal_receiver;
|
||||
|
||||
Append_list<Cpu_thread_component> _thread_list;
|
||||
Append_list<Cpu_thread_component> _thread_list;
|
||||
|
||||
bool _stop_new_threads = true;
|
||||
Lock _stop_new_threads_lock;
|
||||
bool _stop_new_threads = true;
|
||||
Lock _stop_new_threads_lock;
|
||||
|
||||
Capability<Cpu_session::Native_cpu> _native_cpu_cap;
|
||||
Capability<Cpu_session::Native_cpu> _native_cpu_cap;
|
||||
|
||||
Capability<Cpu_session::Native_cpu> _setup_native_cpu();
|
||||
Capability<Cpu_session::Native_cpu> _setup_native_cpu();
|
||||
void _cleanup_native_cpu();
|
||||
|
||||
public:
|
||||
@ -76,11 +76,11 @@ class Gdb_monitor::Cpu_session_component : public Rpc_object<Cpu_session>
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Cpu_session_component(Genode::Env &env,
|
||||
Cpu_session_component(Env &env,
|
||||
Rpc_entrypoint &ep,
|
||||
Allocator *md_alloc,
|
||||
Allocator &md_alloc,
|
||||
Pd_session_capability core_pd,
|
||||
Signal_receiver *exception_signal_receiver,
|
||||
Signal_receiver &exception_signal_receiver,
|
||||
const char *args,
|
||||
Affinity const &affinity);
|
||||
|
||||
@ -91,7 +91,7 @@ class Gdb_monitor::Cpu_session_component : public Rpc_object<Cpu_session>
|
||||
|
||||
Cpu_session &parent_cpu_session();
|
||||
Rpc_entrypoint &thread_ep();
|
||||
Signal_receiver *exception_signal_receiver();
|
||||
Signal_receiver &exception_signal_receiver();
|
||||
Thread_capability thread_cap(unsigned long lwpid);
|
||||
unsigned long lwpid(Thread_capability thread_cap);
|
||||
Cpu_thread_component *lookup_cpu_thread(unsigned long lwpid);
|
||||
@ -122,7 +122,7 @@ class Gdb_monitor::Cpu_session_component : public Rpc_object<Cpu_session>
|
||||
Affinity::Space affinity_space() const override;
|
||||
Dataspace_capability trace_control() override;
|
||||
int ref_account(Cpu_session_capability c) override;
|
||||
int transfer_quota(Cpu_session_capability c, Genode::size_t q) override;
|
||||
int transfer_quota(Cpu_session_capability c, size_t q) override;
|
||||
Quota quota() override;
|
||||
Capability<Native_cpu> native_cpu() override;
|
||||
};
|
||||
@ -132,21 +132,22 @@ class Gdb_monitor::Local_cpu_factory : public Cpu_service::Factory
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Env &_env;
|
||||
Genode::Rpc_entrypoint &_ep;
|
||||
Env &_env;
|
||||
Rpc_entrypoint &_ep;
|
||||
|
||||
Allocator *_md_alloc;
|
||||
Allocator &_md_alloc;
|
||||
Pd_session_capability _core_pd;
|
||||
Genode::Signal_receiver *_signal_receiver;
|
||||
Signal_receiver &_signal_receiver;
|
||||
Genode_child_resources *_genode_child_resources;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
Local_cpu_factory(Genode::Env &env, Genode::Rpc_entrypoint &ep,
|
||||
Allocator *md_alloc,
|
||||
Pd_session_capability core_pd,
|
||||
Genode::Signal_receiver *signal_receiver,
|
||||
Local_cpu_factory(Env &env,
|
||||
Rpc_entrypoint &ep,
|
||||
Allocator &md_alloc,
|
||||
Pd_session_capability core_pd,
|
||||
Signal_receiver &signal_receiver,
|
||||
Genode_child_resources *genode_child_resources)
|
||||
: _env(env), _ep(ep),
|
||||
_md_alloc(md_alloc),
|
||||
@ -178,7 +179,7 @@ class Gdb_monitor::Local_cpu_factory : public Cpu_service::Factory
|
||||
|
||||
void destroy(Cpu_session_component &session) override
|
||||
{
|
||||
Genode::destroy(env()->heap(), &session);
|
||||
Genode::destroy(_md_alloc, &session);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 Genode Labs GmbH
|
||||
* Copyright (C) 2016-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -15,6 +15,9 @@
|
||||
/* GDB monitor includes */
|
||||
#include "cpu_thread_component.h"
|
||||
|
||||
/* libc includes */
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* mem-break.c */
|
||||
extern "C" int breakpoint_len;
|
||||
@ -61,6 +64,150 @@ void Cpu_thread_component::_remove_breakpoint_at_first_instruction()
|
||||
}
|
||||
|
||||
|
||||
void Cpu_thread_component::_dispatch_exception(unsigned)
|
||||
{
|
||||
deliver_signal(SIGTRAP);
|
||||
}
|
||||
|
||||
|
||||
void Cpu_thread_component::_dispatch_sigstop(unsigned)
|
||||
{
|
||||
deliver_signal(SIGSTOP);
|
||||
}
|
||||
|
||||
|
||||
void Cpu_thread_component::_dispatch_sigint(unsigned)
|
||||
{
|
||||
deliver_signal(SIGINT);
|
||||
}
|
||||
|
||||
|
||||
Cpu_thread_component::Cpu_thread_component(Cpu_session_component &cpu_session_component,
|
||||
Capability<Pd_session> pd,
|
||||
Cpu_session::Name const &name,
|
||||
Affinity::Location affinity,
|
||||
Cpu_session::Weight weight,
|
||||
addr_t utcb)
|
||||
: _cpu_session_component(cpu_session_component),
|
||||
_parent_cpu_thread(
|
||||
_cpu_session_component.parent_cpu_session().create_thread(pd,
|
||||
name,
|
||||
affinity,
|
||||
weight,
|
||||
utcb)),
|
||||
_exception_dispatcher(
|
||||
_cpu_session_component.exception_signal_receiver(),
|
||||
*this,
|
||||
&Cpu_thread_component::_dispatch_exception),
|
||||
_sigstop_dispatcher(
|
||||
_cpu_session_component.exception_signal_receiver(),
|
||||
*this,
|
||||
&Cpu_thread_component::_dispatch_sigstop),
|
||||
_sigint_dispatcher(
|
||||
_cpu_session_component.exception_signal_receiver(),
|
||||
*this,
|
||||
&Cpu_thread_component::_dispatch_sigint)
|
||||
{
|
||||
_cpu_session_component.thread_ep().manage(this);
|
||||
|
||||
if (pipe(_pipefd) != 0)
|
||||
error("could not create pipe");
|
||||
}
|
||||
|
||||
|
||||
Cpu_thread_component::~Cpu_thread_component()
|
||||
{
|
||||
close(_pipefd[0]);
|
||||
close(_pipefd[1]);
|
||||
|
||||
_cpu_session_component.thread_ep().dissolve(this);
|
||||
}
|
||||
|
||||
|
||||
int Cpu_thread_component::send_signal(int signo)
|
||||
{
|
||||
pause();
|
||||
|
||||
switch (signo) {
|
||||
case SIGSTOP:
|
||||
Signal_transmitter(sigstop_signal_context_cap()).submit();
|
||||
return 1;
|
||||
case SIGINT:
|
||||
Signal_transmitter(sigint_signal_context_cap()).submit();
|
||||
return 1;
|
||||
default:
|
||||
error("unexpected signal ", signo);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int Cpu_thread_component::deliver_signal(int signo)
|
||||
{
|
||||
if ((signo == SIGTRAP) && _initial_sigtrap_pending) {
|
||||
|
||||
_initial_sigtrap_pending = false;
|
||||
|
||||
if (_verbose)
|
||||
log("received initial SIGTRAP for lwpid ", _lwpid);
|
||||
|
||||
if (_lwpid == GENODE_MAIN_LWPID) {
|
||||
_remove_breakpoint_at_first_instruction();
|
||||
_initial_breakpoint_handled = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* The lock guard prevents an interruption by
|
||||
* 'genode_stop_all_threads()', which could cause
|
||||
* the new thread to be resumed when it should be
|
||||
* stopped.
|
||||
*/
|
||||
|
||||
Lock::Guard stop_new_threads_lock_guard(
|
||||
_cpu_session_component.stop_new_threads_lock());
|
||||
|
||||
if (!_cpu_session_component.stop_new_threads())
|
||||
resume();
|
||||
|
||||
/*
|
||||
* gdbserver expects SIGSTOP as first signal of a new thread,
|
||||
* but we cannot write SIGSTOP here, because waitpid() would
|
||||
* detect that the thread is in an exception state and wait
|
||||
* for the SIGTRAP. So SIGINFO ist used for this purpose.
|
||||
*/
|
||||
signo = SIGINFO;
|
||||
}
|
||||
|
||||
switch (signo) {
|
||||
case SIGSTOP:
|
||||
if (_verbose)
|
||||
log("delivering SIGSTOP to thread ", _lwpid);
|
||||
break;
|
||||
case SIGTRAP:
|
||||
if (_verbose)
|
||||
log("delivering SIGTRAP to thread ", _lwpid);
|
||||
break;
|
||||
case SIGSEGV:
|
||||
if (_verbose)
|
||||
log("delivering SIGSEGV to thread ", _lwpid);
|
||||
break;
|
||||
case SIGINT:
|
||||
if (_verbose)
|
||||
log("delivering SIGINT to thread ", _lwpid);
|
||||
break;
|
||||
case SIGINFO:
|
||||
if (_verbose)
|
||||
log("delivering initial SIGSTOP to thread ", _lwpid);
|
||||
break;
|
||||
default:
|
||||
error("unexpected signal ", signo);
|
||||
}
|
||||
|
||||
write(_pipefd[1], &signo, sizeof(signo));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Dataspace_capability Cpu_thread_component::utcb()
|
||||
{
|
||||
return _parent_cpu_thread.utcb();
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 Genode Labs GmbH
|
||||
* Copyright (C) 2016-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -19,10 +19,6 @@
|
||||
#include <cpu_session/cpu_session.h>
|
||||
#include <cpu_thread/client.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "append_list.h"
|
||||
#include "cpu_session_component.h"
|
||||
@ -65,62 +61,20 @@ class Gdb_monitor::Cpu_thread_component : public Rpc_object<Cpu_thread>,
|
||||
bool _set_breakpoint_at_first_instruction(addr_t ip);
|
||||
void _remove_breakpoint_at_first_instruction();
|
||||
|
||||
void _dispatch_exception(unsigned)
|
||||
{
|
||||
deliver_signal(SIGTRAP);
|
||||
}
|
||||
|
||||
void _dispatch_sigstop(unsigned)
|
||||
{
|
||||
deliver_signal(SIGSTOP);
|
||||
}
|
||||
|
||||
void _dispatch_sigint(unsigned)
|
||||
{
|
||||
deliver_signal(SIGINT);
|
||||
}
|
||||
void _dispatch_exception(unsigned);
|
||||
void _dispatch_sigstop(unsigned);
|
||||
void _dispatch_sigint(unsigned);
|
||||
|
||||
public:
|
||||
|
||||
Cpu_thread_component(Cpu_session_component &cpu_session_component,
|
||||
Capability<Pd_session> pd,
|
||||
Cpu_thread_component(Cpu_session_component &cpu_session_component,
|
||||
Capability<Pd_session> pd,
|
||||
Cpu_session::Name const &name,
|
||||
Affinity::Location affinity,
|
||||
Cpu_session::Weight weight,
|
||||
addr_t utcb)
|
||||
: _cpu_session_component(cpu_session_component),
|
||||
_parent_cpu_thread(
|
||||
_cpu_session_component.parent_cpu_session().create_thread(pd,
|
||||
name,
|
||||
affinity,
|
||||
weight,
|
||||
utcb)),
|
||||
_exception_dispatcher(
|
||||
*_cpu_session_component.exception_signal_receiver(),
|
||||
*this,
|
||||
&Cpu_thread_component::_dispatch_exception),
|
||||
_sigstop_dispatcher(
|
||||
*_cpu_session_component.exception_signal_receiver(),
|
||||
*this,
|
||||
&Cpu_thread_component::_dispatch_sigstop),
|
||||
_sigint_dispatcher(
|
||||
*_cpu_session_component.exception_signal_receiver(),
|
||||
*this,
|
||||
&Cpu_thread_component::_dispatch_sigint)
|
||||
{
|
||||
_cpu_session_component.thread_ep().manage(this);
|
||||
Affinity::Location affinity,
|
||||
Cpu_session::Weight weight,
|
||||
addr_t utcb);
|
||||
|
||||
if (pipe(_pipefd) != 0)
|
||||
error("could not create pipe");
|
||||
}
|
||||
|
||||
~Cpu_thread_component()
|
||||
{
|
||||
close(_pipefd[0]);
|
||||
close(_pipefd[1]);
|
||||
|
||||
_cpu_session_component.thread_ep().dissolve(this);
|
||||
}
|
||||
~Cpu_thread_component();
|
||||
|
||||
Signal_context_capability exception_signal_context_cap()
|
||||
{
|
||||
@ -154,89 +108,9 @@ class Gdb_monitor::Cpu_thread_component : public Rpc_object<Cpu_thread>,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int send_signal(int signo)
|
||||
{
|
||||
pause();
|
||||
|
||||
switch (signo) {
|
||||
case SIGSTOP:
|
||||
Signal_transmitter(sigstop_signal_context_cap()).submit();
|
||||
return 1;
|
||||
case SIGINT:
|
||||
Signal_transmitter(sigint_signal_context_cap()).submit();
|
||||
return 1;
|
||||
default:
|
||||
error("unexpected signal ", signo);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int deliver_signal(int signo)
|
||||
{
|
||||
if ((signo == SIGTRAP) && _initial_sigtrap_pending) {
|
||||
|
||||
_initial_sigtrap_pending = false;
|
||||
|
||||
if (_verbose)
|
||||
log("received initial SIGTRAP for lwpid ", _lwpid);
|
||||
|
||||
if (_lwpid == GENODE_MAIN_LWPID) {
|
||||
_remove_breakpoint_at_first_instruction();
|
||||
_initial_breakpoint_handled = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* The lock guard prevents an interruption by
|
||||
* 'genode_stop_all_threads()', which could cause
|
||||
* the new thread to be resumed when it should be
|
||||
* stopped.
|
||||
*/
|
||||
|
||||
Lock::Guard stop_new_threads_lock_guard(
|
||||
_cpu_session_component.stop_new_threads_lock());
|
||||
|
||||
if (!_cpu_session_component.stop_new_threads())
|
||||
resume();
|
||||
|
||||
/*
|
||||
* gdbserver expects SIGSTOP as first signal of a new thread,
|
||||
* but we cannot write SIGSTOP here, because waitpid() would
|
||||
* detect that the thread is in an exception state and wait
|
||||
* for the SIGTRAP. So SIGINFO ist used for this purpose.
|
||||
*/
|
||||
signo = SIGINFO;
|
||||
}
|
||||
|
||||
switch (signo) {
|
||||
case SIGSTOP:
|
||||
if (_verbose)
|
||||
log("delivering SIGSTOP to thread ", _lwpid);
|
||||
break;
|
||||
case SIGTRAP:
|
||||
if (_verbose)
|
||||
log("delivering SIGTRAP to thread ", _lwpid);
|
||||
break;
|
||||
case SIGSEGV:
|
||||
if (_verbose)
|
||||
log("delivering SIGSEGV to thread ", _lwpid);
|
||||
break;
|
||||
case SIGINT:
|
||||
if (_verbose)
|
||||
log("delivering SIGINT to thread ", _lwpid);
|
||||
break;
|
||||
case SIGINFO:
|
||||
if (_verbose)
|
||||
log("delivering initial SIGSTOP to thread ", _lwpid);
|
||||
break;
|
||||
default:
|
||||
error("unexpected signal ", signo);
|
||||
}
|
||||
|
||||
write(_pipefd[1], &signo, sizeof(signo));
|
||||
|
||||
return 0;
|
||||
}
|
||||
int send_signal(int signo);
|
||||
|
||||
int deliver_signal(int signo);
|
||||
|
||||
/**************************
|
||||
** CPU thread interface **
|
||||
|
@ -6,15 +6,26 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2016 Genode Labs GmbH
|
||||
* Copyright (C) 2011-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
/* Genode includes */
|
||||
#include <base/env.h>
|
||||
#include <os/config.h>
|
||||
|
||||
/* GDB monitor includes */
|
||||
#include "app_child.h"
|
||||
#include "cpu_thread_component.h"
|
||||
#include "genode_child_resources.h"
|
||||
#include "signal_handler_thread.h"
|
||||
|
||||
/* libc includes */
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern "C" {
|
||||
@ -27,23 +38,6 @@ extern "C" {
|
||||
int linux_detach_one_lwp (struct inferior_list_entry *entry, void *args);
|
||||
}
|
||||
|
||||
#include <base/log.h>
|
||||
#include <base/service.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <cpu_thread/client.h>
|
||||
#include <dataspace/client.h>
|
||||
#include <os/config.h>
|
||||
#include <ram_session/connection.h>
|
||||
#include <rom_session/connection.h>
|
||||
#include <util/xml_node.h>
|
||||
|
||||
#include "app_child.h"
|
||||
#include "cpu_session_component.h"
|
||||
#include "cpu_thread_component.h"
|
||||
#include "genode_child_resources.h"
|
||||
#include "rom.h"
|
||||
#include "signal_handler_thread.h"
|
||||
|
||||
static bool verbose = false;
|
||||
|
||||
Genode::Env *genode_env;
|
||||
@ -60,20 +54,185 @@ static unsigned long sigtrap_lwpid;
|
||||
using namespace Genode;
|
||||
using namespace Gdb_monitor;
|
||||
|
||||
static Genode_child_resources *_genode_child_resources = 0;
|
||||
|
||||
|
||||
Genode_child_resources *genode_child_resources()
|
||||
class Memory_model
|
||||
{
|
||||
return _genode_child_resources;
|
||||
private:
|
||||
|
||||
Lock _lock;
|
||||
|
||||
Region_map_component &_address_space;
|
||||
|
||||
Region_map &_rm;
|
||||
|
||||
/**
|
||||
* Representation of a currently mapped region
|
||||
*/
|
||||
struct Mapped_region
|
||||
{
|
||||
Region_map_component::Region *_region;
|
||||
unsigned char *_local_base;
|
||||
|
||||
Mapped_region() : _region(0), _local_base(0) { }
|
||||
|
||||
bool valid() { return _region != 0; }
|
||||
|
||||
bool loaded(Region_map_component::Region const * region)
|
||||
{
|
||||
return _region == region;
|
||||
}
|
||||
|
||||
void flush(Region_map &rm)
|
||||
{
|
||||
if (!valid()) return;
|
||||
rm.detach(_local_base);
|
||||
_local_base = 0;
|
||||
_region = 0;
|
||||
}
|
||||
|
||||
void load(Region_map_component::Region *region, Region_map &rm)
|
||||
{
|
||||
if (region == _region)
|
||||
return;
|
||||
|
||||
if (!region || valid())
|
||||
flush(rm);
|
||||
|
||||
if (!region)
|
||||
return;
|
||||
|
||||
try {
|
||||
_region = region;
|
||||
_local_base = rm.attach(_region->ds_cap(),
|
||||
0, _region->offset());
|
||||
} catch (Region_map::Attach_failed) {
|
||||
flush(rm);
|
||||
error(__func__, ": RM attach failed");
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char *local_base() { return _local_base; }
|
||||
};
|
||||
|
||||
enum { NUM_MAPPED_REGIONS = 1 };
|
||||
|
||||
Mapped_region _mapped_region[NUM_MAPPED_REGIONS];
|
||||
|
||||
unsigned _evict_idx = 0;
|
||||
|
||||
/**
|
||||
* Return local address of mapped region
|
||||
*
|
||||
* The function returns 0 if the mapping fails
|
||||
*/
|
||||
unsigned char *_update_curr_region(Region_map_component::Region *region)
|
||||
{
|
||||
for (unsigned i = 0; i < NUM_MAPPED_REGIONS; i++) {
|
||||
if (_mapped_region[i].loaded(region))
|
||||
return _mapped_region[i].local_base();
|
||||
}
|
||||
|
||||
/* flush one currently mapped region */
|
||||
_evict_idx++;
|
||||
if (_evict_idx == NUM_MAPPED_REGIONS)
|
||||
_evict_idx = 0;
|
||||
|
||||
_mapped_region[_evict_idx].load(region, _rm);
|
||||
|
||||
return _mapped_region[_evict_idx].local_base();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Memory_model(Region_map_component &address_space,
|
||||
Region_map &rm)
|
||||
:
|
||||
_address_space(address_space),
|
||||
_rm(rm)
|
||||
{ }
|
||||
|
||||
unsigned char read(void *addr)
|
||||
{
|
||||
Lock::Guard guard(_lock);
|
||||
|
||||
addr_t offset_in_region = 0;
|
||||
|
||||
Region_map_component::Region *region =
|
||||
_address_space.find_region(addr, &offset_in_region);
|
||||
|
||||
unsigned char *local_base = _update_curr_region(region);
|
||||
|
||||
if (!local_base) {
|
||||
warning(__func__, ": no memory at address ", addr);
|
||||
throw No_memory_at_address();
|
||||
}
|
||||
|
||||
unsigned char value =
|
||||
local_base[offset_in_region];
|
||||
|
||||
if (verbose)
|
||||
log(__func__, ": read addr=", addr, ", value=", Hex(value));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void write(void *addr, unsigned char value)
|
||||
{
|
||||
if (verbose)
|
||||
log(__func__, ": write addr=", addr, ", value=", Hex(value));
|
||||
|
||||
Lock::Guard guard(_lock);
|
||||
|
||||
addr_t offset_in_region = 0;
|
||||
Region_map_component::Region *region =
|
||||
_address_space.find_region(addr, &offset_in_region);
|
||||
|
||||
unsigned char *local_base = _update_curr_region(region);
|
||||
|
||||
if (!local_base) {
|
||||
warning(__func__, ": no memory at address=", addr);
|
||||
warning("(attempted to write ", Hex(value), ")");
|
||||
throw No_memory_at_address();
|
||||
}
|
||||
|
||||
local_base[offset_in_region] = value;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static Genode_child_resources *_genode_child_resources = 0;
|
||||
static Memory_model *_memory_model = 0;
|
||||
|
||||
|
||||
Genode_child_resources &genode_child_resources()
|
||||
{
|
||||
if (!_genode_child_resources) {
|
||||
Genode::error("_genode_child_resources is not set");
|
||||
abort();
|
||||
}
|
||||
|
||||
return *_genode_child_resources;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return singleton instance of memory model
|
||||
*/
|
||||
Memory_model &memory_model()
|
||||
{
|
||||
if (!_memory_model) {
|
||||
Genode::error("_memory_model is not set");
|
||||
abort();
|
||||
}
|
||||
|
||||
return *_memory_model;
|
||||
}
|
||||
|
||||
|
||||
static void genode_stop_thread(unsigned long lwpid)
|
||||
{
|
||||
Cpu_session_component *csc = genode_child_resources()->cpu_session_component();
|
||||
Cpu_session_component &csc = genode_child_resources().cpu_session_component();
|
||||
|
||||
Cpu_thread_component *cpu_thread = csc->lookup_cpu_thread(lwpid);
|
||||
Cpu_thread_component *cpu_thread = csc.lookup_cpu_thread(lwpid);
|
||||
|
||||
if (!cpu_thread) {
|
||||
error(__PRETTY_FUNCTION__, ": "
|
||||
@ -91,7 +250,7 @@ extern "C" pid_t waitpid(pid_t pid, int *status, int flags)
|
||||
|
||||
fd_set readset;
|
||||
|
||||
Cpu_session_component *csc = genode_child_resources()->cpu_session_component();
|
||||
Cpu_session_component &csc = genode_child_resources().cpu_session_component();
|
||||
|
||||
while(1) {
|
||||
|
||||
@ -104,16 +263,16 @@ extern "C" pid_t waitpid(pid_t pid, int *status, int flags)
|
||||
|
||||
FD_SET(_new_thread_pipe[0], &readset);
|
||||
|
||||
Thread_capability thread_cap = csc->first();
|
||||
Thread_capability thread_cap = csc.first();
|
||||
|
||||
while (thread_cap.valid()) {
|
||||
FD_SET(csc->signal_pipe_read_fd(thread_cap), &readset);
|
||||
thread_cap = csc->next(thread_cap);
|
||||
FD_SET(csc.signal_pipe_read_fd(thread_cap), &readset);
|
||||
thread_cap = csc.next(thread_cap);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
FD_SET(csc->signal_pipe_read_fd(csc->thread_cap(pid)), &readset);
|
||||
FD_SET(csc.signal_pipe_read_fd(csc.thread_cap(pid)), &readset);
|
||||
}
|
||||
|
||||
struct timeval wnohang_timeout = {0, 0};
|
||||
@ -157,21 +316,21 @@ extern "C" pid_t waitpid(pid_t pid, int *status, int flags)
|
||||
|
||||
/* received a signal */
|
||||
|
||||
Thread_capability thread_cap = csc->first();
|
||||
Thread_capability thread_cap = csc.first();
|
||||
|
||||
while (thread_cap.valid()) {
|
||||
if (FD_ISSET(csc->signal_pipe_read_fd(thread_cap), &readset))
|
||||
if (FD_ISSET(csc.signal_pipe_read_fd(thread_cap), &readset))
|
||||
break;
|
||||
thread_cap = csc->next(thread_cap);
|
||||
thread_cap = csc.next(thread_cap);
|
||||
}
|
||||
|
||||
if (!thread_cap.valid())
|
||||
continue;
|
||||
|
||||
int signal;
|
||||
read(csc->signal_pipe_read_fd(thread_cap), &signal, sizeof(signal));
|
||||
read(csc.signal_pipe_read_fd(thread_cap), &signal, sizeof(signal));
|
||||
|
||||
unsigned long lwpid = csc->lwpid(thread_cap);
|
||||
unsigned long lwpid = csc.lwpid(thread_cap);
|
||||
|
||||
if (verbose)
|
||||
log("thread ", lwpid, " received signal ", signal);
|
||||
@ -191,13 +350,13 @@ extern "C" pid_t waitpid(pid_t pid, int *status, int flags)
|
||||
* delivered first, otherwise gdbserver would single-step the thread again.
|
||||
*/
|
||||
|
||||
Cpu_thread_component *cpu_thread = csc->lookup_cpu_thread(lwpid);
|
||||
Cpu_thread_component *cpu_thread = csc.lookup_cpu_thread(lwpid);
|
||||
|
||||
Thread_state thread_state = cpu_thread->state();
|
||||
|
||||
if (thread_state.exception) {
|
||||
/* resend the SIGSTOP signal */
|
||||
csc->send_signal(cpu_thread->cap(), SIGSTOP);
|
||||
csc.send_signal(cpu_thread->cap(), SIGSTOP);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -308,26 +467,31 @@ extern "C" int fork()
|
||||
return -1;
|
||||
}
|
||||
|
||||
Number_of_bytes ram_quota = env()->ram_session()->avail() - preserved_ram_quota;
|
||||
Number_of_bytes ram_quota = genode_env->ram().avail() - preserved_ram_quota;
|
||||
|
||||
/* start the application */
|
||||
|
||||
static Heap alloc(genode_env->ram(), genode_env->rm());
|
||||
|
||||
static Signal_receiver signal_receiver;
|
||||
|
||||
static Gdb_monitor::Signal_handler_thread
|
||||
signal_handler_thread(&signal_receiver);
|
||||
signal_handler_thread(*genode_env, signal_receiver);
|
||||
signal_handler_thread.start();
|
||||
|
||||
App_child *child = new (env()->heap()) App_child(*genode_env,
|
||||
filename,
|
||||
genode_env->pd(),
|
||||
genode_env->rm(),
|
||||
ram_quota,
|
||||
&signal_receiver,
|
||||
target_node);
|
||||
App_child *child = new (alloc) App_child(*genode_env,
|
||||
alloc,
|
||||
filename,
|
||||
ram_quota,
|
||||
signal_receiver,
|
||||
target_node);
|
||||
|
||||
_genode_child_resources = child->genode_child_resources();
|
||||
|
||||
static Memory_model memory_model(genode_child_resources().region_map_component(), genode_env->rm());
|
||||
|
||||
_memory_model = &memory_model;
|
||||
|
||||
try {
|
||||
child->start();
|
||||
} catch (...) {
|
||||
@ -341,9 +505,9 @@ extern "C" int fork()
|
||||
|
||||
extern "C" int kill(pid_t pid, int sig)
|
||||
{
|
||||
Cpu_session_component *csc = genode_child_resources()->cpu_session_component();
|
||||
Cpu_session_component &csc = genode_child_resources().cpu_session_component();
|
||||
|
||||
Thread_capability thread_cap = csc->thread_cap(pid);
|
||||
Thread_capability thread_cap = csc.thread_cap(pid);
|
||||
|
||||
if (!thread_cap.valid()) {
|
||||
error(__PRETTY_FUNCTION__, ": "
|
||||
@ -351,14 +515,14 @@ extern "C" int kill(pid_t pid, int sig)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return csc->send_signal(thread_cap, sig);
|
||||
return csc.send_signal(thread_cap, sig);
|
||||
}
|
||||
|
||||
|
||||
extern "C" int initial_breakpoint_handler(CORE_ADDR addr)
|
||||
{
|
||||
Cpu_session_component *csc = genode_child_resources()->cpu_session_component();
|
||||
return csc->handle_initial_breakpoint(sigtrap_lwpid);
|
||||
Cpu_session_component &csc = genode_child_resources().cpu_session_component();
|
||||
return csc.handle_initial_breakpoint(sigtrap_lwpid);
|
||||
}
|
||||
|
||||
|
||||
@ -378,15 +542,15 @@ void genode_remove_thread(unsigned long lwpid)
|
||||
|
||||
extern "C" void genode_stop_all_threads()
|
||||
{
|
||||
Cpu_session_component *csc = genode_child_resources()->cpu_session_component();
|
||||
csc->pause_all_threads();
|
||||
Cpu_session_component &csc = genode_child_resources().cpu_session_component();
|
||||
csc.pause_all_threads();
|
||||
}
|
||||
|
||||
|
||||
void genode_resume_all_threads()
|
||||
{
|
||||
Cpu_session_component *csc = genode_child_resources()->cpu_session_component();
|
||||
csc->resume_all_threads();
|
||||
Cpu_session_component &csc = genode_child_resources().cpu_session_component();
|
||||
csc.resume_all_threads();
|
||||
}
|
||||
|
||||
|
||||
@ -409,9 +573,9 @@ int genode_kill(int pid)
|
||||
|
||||
void genode_continue_thread(unsigned long lwpid, int single_step)
|
||||
{
|
||||
Cpu_session_component *csc = genode_child_resources()->cpu_session_component();
|
||||
Cpu_session_component &csc = genode_child_resources().cpu_session_component();
|
||||
|
||||
Cpu_thread_component *cpu_thread = csc->lookup_cpu_thread(lwpid);
|
||||
Cpu_thread_component *cpu_thread = csc.lookup_cpu_thread(lwpid);
|
||||
|
||||
if (!cpu_thread) {
|
||||
error(__func__, ": " "could not find CPU thread object for lwpid ", lwpid);
|
||||
@ -465,160 +629,9 @@ void genode_store_registers(struct regcache *regcache, int regno)
|
||||
}
|
||||
|
||||
|
||||
class Memory_model
|
||||
{
|
||||
private:
|
||||
|
||||
Lock _lock;
|
||||
|
||||
Region_map_component * const _address_space;
|
||||
|
||||
/**
|
||||
* Representation of a currently mapped region
|
||||
*/
|
||||
struct Mapped_region
|
||||
{
|
||||
Region_map_component::Region *_region;
|
||||
unsigned char *_local_base;
|
||||
|
||||
Mapped_region() : _region(0), _local_base(0) { }
|
||||
|
||||
bool valid() { return _region != 0; }
|
||||
|
||||
bool loaded(Region_map_component::Region const * region)
|
||||
{
|
||||
return _region == region;
|
||||
}
|
||||
|
||||
void flush()
|
||||
{
|
||||
if (!valid()) return;
|
||||
env()->rm_session()->detach(_local_base);
|
||||
_local_base = 0;
|
||||
_region = 0;
|
||||
}
|
||||
|
||||
void load(Region_map_component::Region *region)
|
||||
{
|
||||
if (region == _region)
|
||||
return;
|
||||
|
||||
if (!region || valid())
|
||||
flush();
|
||||
|
||||
if (!region)
|
||||
return;
|
||||
|
||||
try {
|
||||
_region = region;
|
||||
_local_base = env()->rm_session()->attach(_region->ds_cap(),
|
||||
0, _region->offset());
|
||||
} catch (Region_map::Attach_failed) {
|
||||
flush();
|
||||
error(__func__, ": RM attach failed");
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char *local_base() { return _local_base; }
|
||||
};
|
||||
|
||||
enum { NUM_MAPPED_REGIONS = 1 };
|
||||
|
||||
Mapped_region _mapped_region[NUM_MAPPED_REGIONS];
|
||||
|
||||
unsigned _evict_idx;
|
||||
|
||||
/**
|
||||
* Return local address of mapped region
|
||||
*
|
||||
* The function returns 0 if the mapping fails
|
||||
*/
|
||||
unsigned char *_update_curr_region(Region_map_component::Region *region)
|
||||
{
|
||||
for (unsigned i = 0; i < NUM_MAPPED_REGIONS; i++) {
|
||||
if (_mapped_region[i].loaded(region))
|
||||
return _mapped_region[i].local_base();
|
||||
}
|
||||
|
||||
/* flush one currently mapped region */
|
||||
_evict_idx++;
|
||||
if (_evict_idx == NUM_MAPPED_REGIONS)
|
||||
_evict_idx = 0;
|
||||
|
||||
_mapped_region[_evict_idx].load(region);
|
||||
|
||||
return _mapped_region[_evict_idx].local_base();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Memory_model(Region_map_component *address_space)
|
||||
:
|
||||
_address_space(address_space), _evict_idx(0)
|
||||
{ }
|
||||
|
||||
unsigned char read(void *addr)
|
||||
{
|
||||
Lock::Guard guard(_lock);
|
||||
|
||||
addr_t offset_in_region = 0;
|
||||
|
||||
Region_map_component::Region *region =
|
||||
_address_space->find_region(addr, &offset_in_region);
|
||||
|
||||
unsigned char *local_base = _update_curr_region(region);
|
||||
|
||||
if (!local_base) {
|
||||
warning(__func__, ": no memory at address ", addr);
|
||||
throw No_memory_at_address();
|
||||
}
|
||||
|
||||
unsigned char value =
|
||||
local_base[offset_in_region];
|
||||
|
||||
if (verbose)
|
||||
log(__func__, ": read addr=", addr, ", value=", Hex(value));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void write(void *addr, unsigned char value)
|
||||
{
|
||||
if (verbose)
|
||||
log(__func__, ": write addr=", addr, ", value=", Hex(value));
|
||||
|
||||
Lock::Guard guard(_lock);
|
||||
|
||||
addr_t offset_in_region = 0;
|
||||
Region_map_component::Region *region =
|
||||
_address_space->find_region(addr, &offset_in_region);
|
||||
|
||||
unsigned char *local_base = _update_curr_region(region);
|
||||
|
||||
if (!local_base) {
|
||||
warning(__func__, ": no memory at address=", addr);
|
||||
warning("(attempted to write ", Hex(value), ")");
|
||||
throw No_memory_at_address();
|
||||
}
|
||||
|
||||
local_base[offset_in_region] = value;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Return singleton instance of memory model
|
||||
*/
|
||||
static Memory_model *memory_model()
|
||||
{
|
||||
static Memory_model inst(genode_child_resources()->region_map_component());
|
||||
return &inst;
|
||||
}
|
||||
|
||||
|
||||
unsigned char genode_read_memory_byte(void *addr)
|
||||
{
|
||||
return memory_model()->read(addr);
|
||||
return memory_model().read(addr);
|
||||
}
|
||||
|
||||
|
||||
@ -641,7 +654,7 @@ int genode_read_memory(CORE_ADDR memaddr, unsigned char *myaddr, int len)
|
||||
|
||||
void genode_write_memory_byte(void *addr, unsigned char value)
|
||||
{
|
||||
memory_model()->write(addr, value);
|
||||
memory_model().write(addr, value);
|
||||
}
|
||||
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2016 Genode Labs GmbH
|
||||
* Copyright (C) 2011-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -16,6 +16,8 @@
|
||||
|
||||
#include "region_map_component.h"
|
||||
|
||||
extern "C" void abort();
|
||||
|
||||
namespace Gdb_monitor {
|
||||
class Cpu_session_component;
|
||||
class Genode_child_resources;
|
||||
@ -23,7 +25,6 @@ namespace Gdb_monitor {
|
||||
|
||||
class Gdb_monitor::Genode_child_resources
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
Cpu_session_component *_cpu_session_component = 0;
|
||||
@ -41,8 +42,23 @@ class Gdb_monitor::Genode_child_resources
|
||||
_region_map_component = region_map_component;
|
||||
}
|
||||
|
||||
Cpu_session_component *cpu_session_component() { return _cpu_session_component; }
|
||||
Region_map_component *region_map_component() { return _region_map_component; }
|
||||
Cpu_session_component &cpu_session_component()
|
||||
{
|
||||
if (!_cpu_session_component) {
|
||||
Genode::error("_cpu_session_component is not set");
|
||||
abort();
|
||||
}
|
||||
return *_cpu_session_component;
|
||||
}
|
||||
|
||||
Region_map_component ®ion_map_component()
|
||||
{
|
||||
if (!_region_map_component) {
|
||||
Genode::error("_region_map_component is not set");
|
||||
abort();
|
||||
}
|
||||
return *_region_map_component;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _GENODE_CHILD_RESOURCES_H_ */
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 Genode Labs GmbH
|
||||
* Copyright (C) 2016-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -22,9 +22,10 @@
|
||||
#include "region_map_component.h"
|
||||
|
||||
namespace Gdb_monitor {
|
||||
class Pd_session_component;
|
||||
typedef Genode::Local_service<Pd_session_component> Pd_service;
|
||||
using namespace Genode;
|
||||
|
||||
class Pd_session_component;
|
||||
typedef Local_service<Pd_session_component> Pd_service;
|
||||
}
|
||||
|
||||
class Gdb_monitor::Pd_session_component : public Rpc_object<Pd_session>
|
||||
@ -32,6 +33,7 @@ class Gdb_monitor::Pd_session_component : public Rpc_object<Pd_session>
|
||||
private:
|
||||
|
||||
Rpc_entrypoint &_ep;
|
||||
Allocator &_alloc;
|
||||
|
||||
Pd_connection _pd;
|
||||
|
||||
@ -44,13 +46,18 @@ class Gdb_monitor::Pd_session_component : public Rpc_object<Pd_session>
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Pd_session_component(char const *binary_name, Rpc_entrypoint &ep,
|
||||
Pd_session_component(Rpc_entrypoint &ep,
|
||||
Env &env,
|
||||
Allocator &alloc,
|
||||
char const *binary_name,
|
||||
Dataspace_pool &managed_ds_map)
|
||||
:
|
||||
_ep(ep), _pd(binary_name),
|
||||
_address_space(_ep, managed_ds_map, _pd, _pd.address_space()),
|
||||
_stack_area (_ep, managed_ds_map, _pd, _pd.stack_area()),
|
||||
_linker_area (_ep, managed_ds_map, _pd, _pd.linker_area())
|
||||
_ep(ep),
|
||||
_alloc(alloc),
|
||||
_pd(env, binary_name),
|
||||
_address_space(_ep, _alloc, managed_ds_map, _pd, _pd.address_space()),
|
||||
_stack_area (_ep, _alloc, managed_ds_map, _pd, _pd.stack_area()),
|
||||
_linker_area (_ep, _alloc, managed_ds_map, _pd, _pd.linker_area())
|
||||
{
|
||||
_ep.manage(this);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2016 Genode Labs GmbH
|
||||
* Copyright (C) 2011-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -20,7 +20,7 @@
|
||||
using namespace Genode;
|
||||
using namespace Gdb_monitor;
|
||||
|
||||
Ram_session_component::Ram_session_component(Genode::Env &env, const char *args,
|
||||
Ram_session_component::Ram_session_component(Env &env, const char *args,
|
||||
Affinity const &affinity)
|
||||
: _env(env),
|
||||
_parent_ram_session(_env.session<Ram_session>(_id_space_element.id(), args, affinity))
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2016 Genode Labs GmbH
|
||||
* Copyright (C) 2006-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -20,29 +20,30 @@
|
||||
|
||||
namespace Gdb_monitor
|
||||
{
|
||||
class Ram_session_component;
|
||||
using namespace Genode;
|
||||
|
||||
class Ram_session_component;
|
||||
}
|
||||
|
||||
class Gdb_monitor::Ram_session_component : public Rpc_object<Ram_session>
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Env &_env;
|
||||
Env &_env;
|
||||
|
||||
Genode::Parent::Client _parent_client;
|
||||
Parent::Client _parent_client;
|
||||
|
||||
Id_space<Parent::Client>::Element const _id_space_element
|
||||
{ _parent_client, _env.id_space() };
|
||||
|
||||
Genode::Ram_session_client _parent_ram_session;
|
||||
Ram_session_client _parent_ram_session;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Ram_session_component(Genode::Env &env, const char *args,
|
||||
Ram_session_component(Env &env, const char *args,
|
||||
Affinity const &affinity);
|
||||
|
||||
/**
|
||||
@ -55,12 +56,12 @@ class Gdb_monitor::Ram_session_component : public Rpc_object<Ram_session>
|
||||
** RAM Session interface **
|
||||
***************************/
|
||||
|
||||
Ram_dataspace_capability alloc(Genode::size_t, Cache_attribute);
|
||||
Ram_dataspace_capability alloc(size_t, Cache_attribute);
|
||||
void free(Ram_dataspace_capability);
|
||||
int ref_account(Ram_session_capability);
|
||||
int transfer_quota(Ram_session_capability, Genode::size_t);
|
||||
Genode::size_t quota();
|
||||
Genode::size_t used();
|
||||
int transfer_quota(Ram_session_capability, size_t);
|
||||
size_t quota();
|
||||
size_t used();
|
||||
};
|
||||
|
||||
#endif /* _RAM_SESSION_COMPONENT_H_ */
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2016 Genode Labs GmbH
|
||||
* Copyright (C) 2011-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -75,7 +75,7 @@ Region_map_component::attach(Dataspace_capability ds_cap, size_t size,
|
||||
executable);
|
||||
|
||||
Lock::Guard lock_guard(_region_map_lock);
|
||||
_region_map.insert(new (env()->heap()) Region(addr, (void*)((addr_t)addr + size - 1), ds_cap, offset));
|
||||
_region_map.insert(new (_alloc) Region(addr, (void*)((addr_t)addr + size - 1), ds_cap, offset));
|
||||
|
||||
return addr;
|
||||
}
|
||||
@ -92,7 +92,7 @@ void Region_map_component::detach(Region_map::Local_addr local_addr)
|
||||
return;
|
||||
}
|
||||
_region_map.remove(region);
|
||||
destroy(env()->heap(), region);
|
||||
destroy(_alloc, region);
|
||||
}
|
||||
|
||||
|
||||
@ -111,16 +111,18 @@ Region_map::State Region_map_component::state()
|
||||
Dataspace_capability Region_map_component::dataspace()
|
||||
{
|
||||
Dataspace_capability ds_cap = _parent_region_map.dataspace();
|
||||
_managed_ds_map.insert(new (env()->heap()) Dataspace_object(ds_cap, this));
|
||||
_managed_ds_map.insert(new (_alloc) Dataspace_object(ds_cap, this));
|
||||
return ds_cap;
|
||||
}
|
||||
|
||||
Region_map_component::Region_map_component(Rpc_entrypoint &ep,
|
||||
Allocator &alloc,
|
||||
Dataspace_pool &managed_ds_map,
|
||||
Pd_session_capability pd,
|
||||
Capability<Region_map> parent_region_map)
|
||||
:
|
||||
_ep(ep),
|
||||
_alloc(alloc),
|
||||
_pd(pd),
|
||||
_parent_region_map(parent_region_map),
|
||||
_managed_ds_map(managed_ds_map)
|
||||
|
@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2016 Genode Labs GmbH
|
||||
* Copyright (C) 2006-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -31,11 +31,13 @@ namespace Gdb_monitor {
|
||||
{
|
||||
private:
|
||||
|
||||
Rpc_entrypoint &_ep;
|
||||
Rpc_entrypoint &_ep;
|
||||
|
||||
Pd_session_capability _pd;
|
||||
Allocator &_alloc;
|
||||
|
||||
Genode::Region_map_client _parent_region_map;
|
||||
Pd_session_capability _pd;
|
||||
|
||||
Region_map_client _parent_region_map;
|
||||
|
||||
public:
|
||||
|
||||
@ -44,7 +46,7 @@ namespace Gdb_monitor {
|
||||
private:
|
||||
void *_start;
|
||||
void *_end;
|
||||
Genode::off_t _offset;
|
||||
off_t _offset;
|
||||
Dataspace_capability _ds_cap;
|
||||
|
||||
public:
|
||||
@ -63,7 +65,7 @@ namespace Gdb_monitor {
|
||||
}
|
||||
|
||||
void *start() { return _start; }
|
||||
Genode::off_t offset() { return _offset; }
|
||||
off_t offset() { return _offset; }
|
||||
Dataspace_capability ds_cap() { return _ds_cap; }
|
||||
};
|
||||
|
||||
@ -78,9 +80,10 @@ namespace Gdb_monitor {
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Region_map_component(Rpc_entrypoint &ep,
|
||||
Dataspace_pool &managed_ds_map,
|
||||
Pd_session_capability pd,
|
||||
Region_map_component(Rpc_entrypoint &ep,
|
||||
Allocator &alloc,
|
||||
Dataspace_pool &managed_ds_map,
|
||||
Pd_session_capability pd,
|
||||
Capability<Region_map> parent_region_map);
|
||||
|
||||
~Region_map_component();
|
||||
@ -98,8 +101,8 @@ namespace Gdb_monitor {
|
||||
** Region manager session interface **
|
||||
**************************************/
|
||||
|
||||
Local_addr attach (Dataspace_capability, Genode::size_t,
|
||||
Genode::off_t, bool, Local_addr, bool) override;
|
||||
Local_addr attach (Dataspace_capability, size_t,
|
||||
off_t, bool, Local_addr, bool) override;
|
||||
void detach (Local_addr) override;
|
||||
void fault_handler (Signal_context_capability) override;
|
||||
State state () override;
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2016 Genode Labs GmbH
|
||||
* Copyright (C) 2011-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -24,38 +24,11 @@
|
||||
|
||||
namespace Gdb_monitor
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
class Rom_session_component;
|
||||
class Local_rom_factory;
|
||||
typedef Genode::Local_service<Rom_session_component> Rom_service;
|
||||
|
||||
using namespace Genode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone a ROM dataspace in RAM
|
||||
*/
|
||||
static Genode::Capability<Genode::Ram_dataspace>
|
||||
clone_rom(Genode::Capability<Genode::Rom_dataspace> rom_cap)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
Genode::size_t rom_size = Dataspace_client(rom_cap).size();
|
||||
Capability<Ram_dataspace> clone_cap = env()->ram_session()->alloc(rom_size);
|
||||
|
||||
if (!clone_cap.valid()) {
|
||||
error(__func__, ": memory allocation for cloned dataspace failed");
|
||||
return Capability<Ram_dataspace>();
|
||||
}
|
||||
|
||||
void *rom = env()->rm_session()->attach(rom_cap);
|
||||
void *clone = env()->rm_session()->attach(clone_cap);
|
||||
|
||||
Genode::memcpy(clone, rom, rom_size);
|
||||
|
||||
env()->rm_session()->detach(rom);
|
||||
env()->rm_session()->detach(clone);
|
||||
|
||||
return clone_cap;
|
||||
typedef Local_service<Rom_session_component> Rom_service;
|
||||
}
|
||||
|
||||
|
||||
@ -66,20 +39,51 @@ class Gdb_monitor::Rom_session_component : public Rpc_object<Rom_session>
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Rpc_entrypoint &_ep;
|
||||
Env &_env;
|
||||
Rpc_entrypoint &_ep;
|
||||
|
||||
Capability<Ram_dataspace> _clone_cap;
|
||||
|
||||
/**
|
||||
* Clone a ROM dataspace in RAM
|
||||
*/
|
||||
Capability<Ram_dataspace> _clone_rom(Capability<Rom_dataspace> rom_cap)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
size_t rom_size = Dataspace_client(rom_cap).size();
|
||||
Capability<Ram_dataspace> clone_cap = _env.ram().alloc(rom_size);
|
||||
|
||||
if (!clone_cap.valid()) {
|
||||
error(__func__, ": memory allocation for cloned dataspace failed");
|
||||
return Capability<Ram_dataspace>();
|
||||
}
|
||||
|
||||
void *rom = _env.rm().attach(rom_cap);
|
||||
void *clone = _env.rm().attach(clone_cap);
|
||||
|
||||
memcpy(clone, rom, rom_size);
|
||||
|
||||
_env.rm().detach(rom);
|
||||
_env.rm().detach(clone);
|
||||
|
||||
return clone_cap;
|
||||
}
|
||||
|
||||
Capability<Ram_dataspace> _clone_cap;
|
||||
|
||||
public:
|
||||
|
||||
Rom_session_component(Genode::Rpc_entrypoint &ep, char const *filename)
|
||||
: _ep(ep),
|
||||
_clone_cap(clone_rom(Rom_connection(filename).dataspace()))
|
||||
Rom_session_component(Env &env,
|
||||
Rpc_entrypoint &ep,
|
||||
char const *filename)
|
||||
: _env(env),
|
||||
_ep(ep),
|
||||
_clone_cap(_clone_rom(Rom_connection(env, filename).dataspace()))
|
||||
{ _ep.manage(this); }
|
||||
|
||||
~Rom_session_component()
|
||||
{
|
||||
env()->ram_session()->free(_clone_cap);
|
||||
_env.ram().free(_clone_cap);
|
||||
_ep.dissolve(this);
|
||||
}
|
||||
|
||||
@ -93,7 +97,7 @@ class Gdb_monitor::Rom_session_component : public Rpc_object<Rom_session>
|
||||
static_cap_cast<Dataspace>(_clone_cap));
|
||||
}
|
||||
|
||||
void sigh(Genode::Signal_context_capability) override { }
|
||||
void sigh(Signal_context_capability) override { }
|
||||
};
|
||||
|
||||
|
||||
@ -101,13 +105,14 @@ class Gdb_monitor::Local_rom_factory : public Rom_service::Factory
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Env &_env;
|
||||
Genode::Rpc_entrypoint &_ep;
|
||||
Env &_env;
|
||||
Rpc_entrypoint &_ep;
|
||||
Allocator &_alloc;
|
||||
|
||||
public:
|
||||
|
||||
Local_rom_factory(Genode::Env &env, Genode::Rpc_entrypoint &ep)
|
||||
: _env(env), _ep(ep) { }
|
||||
Local_rom_factory(Env &env, Rpc_entrypoint &ep, Allocator &alloc)
|
||||
: _env(env), _ep(ep), _alloc(alloc) { }
|
||||
|
||||
/***********************
|
||||
** Factory interface **
|
||||
@ -117,15 +122,17 @@ class Gdb_monitor::Local_rom_factory : public Rom_service::Factory
|
||||
{
|
||||
Session_label const label = label_from_args(args.string());
|
||||
|
||||
return *new (env()->heap())
|
||||
Rom_session_component(_ep, label.last_element().string());
|
||||
return *new (_alloc)
|
||||
Rom_session_component(_env,
|
||||
_ep,
|
||||
label.last_element().string());
|
||||
}
|
||||
|
||||
void upgrade(Rom_session_component &, Args const &) override { }
|
||||
|
||||
void destroy(Rom_session_component &session) override
|
||||
{
|
||||
Genode::destroy(env()->heap(), &session);
|
||||
Genode::destroy(_alloc, &session);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2016 Genode Labs GmbH
|
||||
* Copyright (C) 2011-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -16,16 +16,17 @@
|
||||
using namespace Genode;
|
||||
using namespace Gdb_monitor;
|
||||
|
||||
Signal_handler_thread::Signal_handler_thread(Signal_receiver *receiver)
|
||||
Signal_handler_thread::Signal_handler_thread(Env &env,
|
||||
Signal_receiver &receiver)
|
||||
:
|
||||
Thread_deprecated<SIGNAL_HANDLER_THREAD_STACK_SIZE>("sig_handler"),
|
||||
Thread(env, "sig_handler", SIGNAL_HANDLER_THREAD_STACK_SIZE),
|
||||
_signal_receiver(receiver) { }
|
||||
|
||||
|
||||
void Signal_handler_thread::entry()
|
||||
{
|
||||
while(1) {
|
||||
Signal s = _signal_receiver->wait_for_signal();
|
||||
Signal s = _signal_receiver.wait_for_signal();
|
||||
|
||||
Signal_dispatcher_base *signal_dispatcher =
|
||||
dynamic_cast<Signal_dispatcher_base*>(s.context());
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2016 Genode Labs GmbH
|
||||
* Copyright (C) 2011-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -17,22 +17,21 @@
|
||||
#include <base/signal.h>
|
||||
#include <base/thread.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
namespace Gdb_monitor {
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
enum { SIGNAL_HANDLER_THREAD_STACK_SIZE = 2*1024*sizeof(addr_t) };
|
||||
|
||||
class Signal_handler_thread
|
||||
: public Thread_deprecated<SIGNAL_HANDLER_THREAD_STACK_SIZE>
|
||||
class Signal_handler_thread : public Thread
|
||||
{
|
||||
private:
|
||||
|
||||
Signal_receiver *_signal_receiver;
|
||||
Signal_receiver &_signal_receiver;
|
||||
|
||||
public:
|
||||
|
||||
Signal_handler_thread(Signal_receiver *receiver);
|
||||
Signal_handler_thread(Env &env, Signal_receiver &receiver);
|
||||
void entry();
|
||||
};
|
||||
|
||||
|
@ -5,12 +5,17 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2016 Genode Labs GmbH
|
||||
* Copyright (C) 2011-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <cpu_thread/client.h>
|
||||
|
||||
#include "cpu_session_component.h"
|
||||
#include "genode_child_resources.h"
|
||||
|
||||
extern "C" {
|
||||
#define private _private
|
||||
#include "server.h"
|
||||
@ -19,11 +24,6 @@ extern "C" {
|
||||
#define _private private
|
||||
}
|
||||
|
||||
#include <cpu_thread/client.h>
|
||||
|
||||
#include "cpu_session_component.h"
|
||||
#include "genode_child_resources.h"
|
||||
|
||||
using namespace Genode;
|
||||
using namespace Gdb_monitor;
|
||||
|
||||
@ -35,11 +35,11 @@ static constexpr bool verbose = false;
|
||||
|
||||
Thread_state get_current_thread_state()
|
||||
{
|
||||
Cpu_session_component *csc = genode_child_resources()->cpu_session_component();
|
||||
Cpu_session_component &csc = genode_child_resources()->cpu_session_component();
|
||||
|
||||
ptid_t ptid = ((struct inferior_list_entry*)current_inferior)->id;
|
||||
|
||||
Cpu_thread_client cpu_thread(csc->thread_cap(ptid.lwp));
|
||||
Cpu_thread_client cpu_thread(csc.thread_cap(ptid.lwp));
|
||||
|
||||
return cpu_thread.state();
|
||||
}
|
||||
@ -47,11 +47,11 @@ Thread_state get_current_thread_state()
|
||||
|
||||
void set_current_thread_state(Thread_state thread_state)
|
||||
{
|
||||
Cpu_session_component *csc = genode_child_resources()->cpu_session_component();
|
||||
Cpu_session_component &csc = genode_child_resources()->cpu_session_component();
|
||||
|
||||
ptid_t ptid = ((struct inferior_list_entry*)current_inferior)->id;
|
||||
|
||||
Cpu_thread_client cpu_thread(csc->thread_cap(ptid.lwp));
|
||||
Cpu_thread_client cpu_thread(csc.thread_cap(ptid.lwp));
|
||||
|
||||
cpu_thread.state(thread_state);
|
||||
}
|
||||
|
@ -5,25 +5,28 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2016 Genode Labs GmbH
|
||||
* Copyright (C) 2011-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
|
||||
/* GDB monitor includes */
|
||||
#include "cpu_session_component.h"
|
||||
#include "reg-arm.h"
|
||||
#include "gdbserver_platform_helper.h"
|
||||
|
||||
#include "genode_child_resources.h"
|
||||
|
||||
extern "C" {
|
||||
#define private _private
|
||||
#include "genode-low.h"
|
||||
#define _private private
|
||||
}
|
||||
|
||||
#include <base/log.h>
|
||||
#include "cpu_session_component.h"
|
||||
#include "reg-arm.h"
|
||||
#include "gdbserver_platform_helper.h"
|
||||
|
||||
#include "genode_child_resources.h"
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
static bool in_syscall(Thread_state const &ts)
|
||||
|
@ -5,24 +5,27 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2016 Genode Labs GmbH
|
||||
* Copyright (C) 2011-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
|
||||
/* GDB monitor includes */
|
||||
#include "i386.h"
|
||||
#include "cpu_session_component.h"
|
||||
#include "gdbserver_platform_helper.h"
|
||||
#include "genode_child_resources.h"
|
||||
|
||||
extern "C" {
|
||||
#define private _private
|
||||
#include "genode-low.h"
|
||||
#define _private private
|
||||
}
|
||||
|
||||
#include <base/log.h>
|
||||
#include "i386.h"
|
||||
#include "cpu_session_component.h"
|
||||
#include "gdbserver_platform_helper.h"
|
||||
#include "genode_child_resources.h"
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
static bool in_syscall(Thread_state const &thread_state)
|
||||
|
Loading…
Reference in New Issue
Block a user