2011-12-22 16:19:25 +01:00
|
|
|
/*
|
|
|
|
* \brief Genode backend for GDBServer (C++)
|
|
|
|
* \author Christian Prochaska
|
|
|
|
* \author Norman Feske
|
|
|
|
* \date 2011-05-06
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-01-04 11:38:39 +01:00
|
|
|
* Copyright (C) 2011-2017 Genode Labs GmbH
|
2011-12-22 16:19:25 +01:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
2017-02-20 13:23:52 +01:00
|
|
|
* under the terms of the GNU Affero General Public License version 3.
|
2011-12-22 16:19:25 +01:00
|
|
|
*/
|
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
/* Genode includes */
|
|
|
|
#include <base/env.h>
|
2017-05-29 14:52:24 +02:00
|
|
|
#include <base/attached_rom_dataspace.h>
|
2017-01-04 11:38:39 +01:00
|
|
|
|
|
|
|
/* GDB monitor includes */
|
|
|
|
#include "app_child.h"
|
|
|
|
#include "cpu_thread_component.h"
|
|
|
|
#include "genode_child_resources.h"
|
|
|
|
|
|
|
|
/* libc includes */
|
2016-05-17 16:13:23 +02:00
|
|
|
#include <sys/ptrace.h>
|
2017-01-04 11:38:39 +01:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/wait.h>
|
2016-05-17 16:13:23 +02:00
|
|
|
#include <unistd.h>
|
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
#include "genode-low.h"
|
2016-05-17 16:13:23 +02:00
|
|
|
#include "server.h"
|
2011-12-22 16:19:25 +01:00
|
|
|
#include "linux-low.h"
|
|
|
|
|
2019-04-29 16:53:44 +02:00
|
|
|
void linux_detach_one_lwp (struct lwp_info *lwp);
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
static bool verbose = false;
|
|
|
|
|
2016-11-23 17:07:49 +01:00
|
|
|
Genode::Env *genode_env;
|
|
|
|
|
2019-04-29 16:53:44 +02:00
|
|
|
/*
|
|
|
|
* 'waitpid()' is implemented using 'select()'. When a new thread is created,
|
|
|
|
* 'select()' needs to unblock, so there is a dedicated pipe for that. The
|
|
|
|
* lwpid of the new thread needs to be read from the pipe in 'waitpid()', so
|
|
|
|
* that the next 'select()' call can block again. The lwpid needs to be stored
|
|
|
|
* in a variable until it is inquired later.
|
|
|
|
*/
|
2016-05-17 16:13:23 +02:00
|
|
|
static int _new_thread_pipe[2];
|
2019-04-29 16:53:44 +02:00
|
|
|
static unsigned long _new_thread_lwpid;
|
2016-05-17 16:13:23 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* When 'waitpid()' reports a SIGTRAP, this variable stores the lwpid of the
|
|
|
|
* corresponding thread. This information is used in the initial breakpoint
|
|
|
|
* handler to let the correct thread handle the event.
|
|
|
|
*/
|
2019-04-29 16:53:44 +02:00
|
|
|
static unsigned long _sigtrap_lwpid;
|
2016-05-17 16:13:23 +02:00
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
using namespace Genode;
|
|
|
|
using namespace Gdb_monitor;
|
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
class Memory_model
|
|
|
|
{
|
|
|
|
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());
|
Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-07 22:03:22 +02:00
|
|
|
}
|
|
|
|
catch (Region_map::Region_conflict) {
|
2017-01-04 11:38:39 +01:00
|
|
|
flush(rm);
|
Streamline exception types
This patch reduces the number of exception types by facilitating
globally defined exceptions for common usage patterns shared by most
services. In particular, RPC functions that demand a session-resource
upgrade not longer reflect this condition via a session-specific
exception but via the 'Out_of_ram' or 'Out_of_caps' types.
Furthermore, the 'Parent::Service_denied', 'Parent::Unavailable',
'Root::Invalid_args', 'Root::Unavailable', 'Service::Invalid_args',
'Service::Unavailable', and 'Local_service::Factory::Denied' types have
been replaced by the single 'Service_denied' exception type defined in
'session/session.h'.
This consolidation eases the error handling (there are fewer exceptions
to handle), alleviates the need to convert exceptions along the
session-creation call chain, and avoids possible aliasing problems
(catching the wrong type with the same name but living in a different
scope).
2017-05-07 22:03:22 +02:00
|
|
|
error(__func__, ": RM attach failed (region conflict)");
|
|
|
|
}
|
|
|
|
catch (Region_map::Invalid_dataspace) {
|
|
|
|
flush(rm);
|
|
|
|
error(__func__, ": RM attach failed (invalid dataspace)");
|
2017-01-04 11:38:39 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
static Genode_child_resources *_genode_child_resources = 0;
|
2017-01-04 11:38:39 +01:00
|
|
|
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();
|
|
|
|
}
|
2016-05-17 16:13:23 +02:00
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
return *_genode_child_resources;
|
|
|
|
}
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return singleton instance of memory model
|
|
|
|
*/
|
|
|
|
Memory_model &memory_model()
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
2017-01-04 11:38:39 +01:00
|
|
|
if (!_memory_model) {
|
|
|
|
Genode::error("_memory_model is not set");
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
|
|
|
return *_memory_model;
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
static void genode_stop_thread(unsigned long lwpid)
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
2017-01-04 11:38:39 +01:00
|
|
|
Cpu_session_component &csc = genode_child_resources().cpu_session_component();
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
Cpu_thread_component *cpu_thread = csc.lookup_cpu_thread(lwpid);
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
if (!cpu_thread) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
error(__PRETTY_FUNCTION__, ": "
|
|
|
|
"could not find CPU thread object for lwpid ", lwpid);
|
2016-05-17 16:13:23 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
cpu_thread->pause();
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-04-29 16:53:44 +02:00
|
|
|
pid_t my_waitpid(pid_t pid, int *status, int flags)
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
2016-05-17 16:13:23 +02:00
|
|
|
extern int remote_desc;
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
fd_set readset;
|
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
Cpu_session_component &csc = genode_child_resources().cpu_session_component();
|
2016-05-17 16:13:23 +02:00
|
|
|
|
|
|
|
while(1) {
|
|
|
|
|
|
|
|
FD_ZERO (&readset);
|
|
|
|
|
|
|
|
if (remote_desc != -1)
|
|
|
|
FD_SET (remote_desc, &readset);
|
|
|
|
|
|
|
|
if (pid == -1) {
|
|
|
|
|
|
|
|
FD_SET(_new_thread_pipe[0], &readset);
|
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
Thread_capability thread_cap = csc.first();
|
2016-05-17 16:13:23 +02:00
|
|
|
|
|
|
|
while (thread_cap.valid()) {
|
2017-01-04 11:38:39 +01:00
|
|
|
FD_SET(csc.signal_pipe_read_fd(thread_cap), &readset);
|
|
|
|
thread_cap = csc.next(thread_cap);
|
2016-05-17 16:13:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
FD_SET(csc.signal_pipe_read_fd(csc.thread_cap(pid)), &readset);
|
2016-05-17 16:13:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
struct timeval wnohang_timeout = {0, 0};
|
|
|
|
struct timeval *timeout = (flags & WNOHANG) ? &wnohang_timeout : NULL;
|
|
|
|
|
|
|
|
/* TODO: determine the highest fd in the set for optimization */
|
|
|
|
int res = select(FD_SETSIZE, &readset, 0, 0, timeout);
|
|
|
|
|
|
|
|
if (res > 0) {
|
|
|
|
|
|
|
|
if ((remote_desc != -1) && FD_ISSET(remote_desc, &readset)) {
|
|
|
|
|
|
|
|
/* received input from GDB */
|
|
|
|
|
|
|
|
int cc;
|
|
|
|
char c = 0;
|
|
|
|
|
|
|
|
cc = read (remote_desc, &c, 1);
|
|
|
|
|
2019-04-29 16:53:44 +02:00
|
|
|
if (cc == 1 && c == '\003' && current_thread != NULL) {
|
2016-05-17 16:13:23 +02:00
|
|
|
/* this causes a SIGINT to be delivered to one of the threads */
|
|
|
|
(*the_target->request_interrupt)();
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
if (verbose)
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
log("input_interrupt, "
|
|
|
|
"count=", cc, " c=", c, " ('", Char(c), "%c')");
|
2016-05-17 16:13:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
} else if (FD_ISSET(_new_thread_pipe[0], &readset)) {
|
|
|
|
|
2019-04-29 16:53:44 +02:00
|
|
|
/*
|
|
|
|
* Linux 'ptrace(2)' manual text related to the main thread:
|
|
|
|
*
|
|
|
|
* "If the PTRACE_O_TRACEEXEC option is not in effect, all
|
|
|
|
* successful calls to execve(2) by the traced process will
|
|
|
|
* cause it to be sent a SIGTRAP signal, giving the parent a
|
|
|
|
* chance to gain control before the new program begins
|
|
|
|
* execution."
|
|
|
|
*
|
|
|
|
* Linux 'ptrace' manual text related to other threads:
|
|
|
|
*
|
|
|
|
* "PTRACE_O_CLONE
|
|
|
|
* ...
|
|
|
|
* A waitpid(2) by the tracer will return a status value such
|
|
|
|
* that
|
|
|
|
*
|
|
|
|
* status>>8 == (SIGTRAP | (PTRACE_EVENT_CLONE<<8))
|
|
|
|
*
|
|
|
|
* The PID of the new process can be retrieved with
|
|
|
|
* PTRACE_GETEVENTMSG."
|
|
|
|
*/
|
|
|
|
|
|
|
|
*status = W_STOPCODE(SIGTRAP);
|
|
|
|
|
|
|
|
read(_new_thread_pipe[0], &_new_thread_lwpid,
|
|
|
|
sizeof(_new_thread_lwpid));
|
|
|
|
|
|
|
|
if (_new_thread_lwpid != GENODE_MAIN_LWPID) {
|
|
|
|
*status |= (PTRACE_EVENT_CLONE << 16);
|
|
|
|
genode_stop_thread(GENODE_MAIN_LWPID);
|
|
|
|
}
|
2016-05-17 16:13:23 +02:00
|
|
|
|
2019-04-29 16:53:44 +02:00
|
|
|
return GENODE_MAIN_LWPID;
|
2016-05-17 16:13:23 +02:00
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
/* received a signal */
|
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
Thread_capability thread_cap = csc.first();
|
2016-05-17 16:13:23 +02:00
|
|
|
|
|
|
|
while (thread_cap.valid()) {
|
2017-01-04 11:38:39 +01:00
|
|
|
if (FD_ISSET(csc.signal_pipe_read_fd(thread_cap), &readset))
|
2016-05-17 16:13:23 +02:00
|
|
|
break;
|
2017-01-04 11:38:39 +01:00
|
|
|
thread_cap = csc.next(thread_cap);
|
2016-05-17 16:13:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!thread_cap.valid())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
int signal;
|
2017-01-04 11:38:39 +01:00
|
|
|
read(csc.signal_pipe_read_fd(thread_cap), &signal, sizeof(signal));
|
2016-05-17 16:13:23 +02:00
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
unsigned long lwpid = csc.lwpid(thread_cap);
|
2016-05-17 16:13:23 +02:00
|
|
|
|
|
|
|
if (verbose)
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
log("thread ", lwpid, " received signal ", signal);
|
2016-05-17 16:13:23 +02:00
|
|
|
|
|
|
|
if (signal == SIGTRAP) {
|
|
|
|
|
2019-04-29 16:53:44 +02:00
|
|
|
_sigtrap_lwpid = lwpid;
|
2016-05-17 16:13:23 +02:00
|
|
|
|
|
|
|
} else if (signal == SIGSTOP) {
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check if a SIGTRAP is pending
|
|
|
|
*
|
|
|
|
* This can happen if a single-stepped thread gets paused while gdbserver
|
|
|
|
* handles a signal of a different thread and the exception signal after
|
|
|
|
* the single step has not arrived yet. In this case, the SIGTRAP must be
|
|
|
|
* delivered first, otherwise gdbserver would single-step the thread again.
|
|
|
|
*/
|
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
Cpu_thread_component *cpu_thread = csc.lookup_cpu_thread(lwpid);
|
2016-05-17 16:13:23 +02:00
|
|
|
|
|
|
|
Thread_state thread_state = cpu_thread->state();
|
|
|
|
|
|
|
|
if (thread_state.exception) {
|
|
|
|
/* resend the SIGSTOP signal */
|
2017-01-04 11:38:39 +01:00
|
|
|
csc.send_signal(cpu_thread->cap(), SIGSTOP);
|
2016-05-17 16:13:23 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (signal == SIGINFO) {
|
|
|
|
|
|
|
|
if (verbose)
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
log("received SIGINFO for new lwpid ", lwpid);
|
2016-05-17 16:13:23 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* First signal of a new thread. On Genode originally a
|
|
|
|
* SIGTRAP, but gdbserver expects SIGSTOP.
|
|
|
|
*/
|
|
|
|
|
|
|
|
signal = SIGSTOP;
|
|
|
|
}
|
|
|
|
|
|
|
|
*status = W_STOPCODE(signal);
|
|
|
|
|
|
|
|
return lwpid;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
return res;
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
extern "C" long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data)
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
2016-05-17 16:13:23 +02:00
|
|
|
const char *request_str = 0;
|
|
|
|
|
|
|
|
switch (request) {
|
|
|
|
case PTRACE_TRACEME: request_str = "PTRACE_TRACEME"; break;
|
|
|
|
case PTRACE_PEEKTEXT: request_str = "PTRACE_PEEKTEXT"; break;
|
|
|
|
case PTRACE_PEEKUSER: request_str = "PTRACE_PEEKUSER"; break;
|
|
|
|
case PTRACE_POKETEXT: request_str = "PTRACE_POKETEXT"; break;
|
|
|
|
case PTRACE_POKEUSER: request_str = "PTRACE_POKEUSER"; break;
|
|
|
|
case PTRACE_CONT: request_str = "PTRACE_CONT"; break;
|
|
|
|
case PTRACE_KILL: request_str = "PTRACE_KILL"; break;
|
|
|
|
case PTRACE_SINGLESTEP: request_str = "PTRACE_SINGLESTEP"; break;
|
|
|
|
case PTRACE_GETREGS: request_str = "PTRACE_GETREGS"; break;
|
|
|
|
case PTRACE_SETREGS: request_str = "PTRACE_SETREGS"; break;
|
|
|
|
case PTRACE_ATTACH: request_str = "PTRACE_ATTACH"; break;
|
|
|
|
case PTRACE_DETACH: request_str = "PTRACE_DETACH"; break;
|
2019-04-29 16:53:44 +02:00
|
|
|
case PTRACE_GETSIGINFO: request_str = "PTRACE_GETSIGINFO"; break;
|
2016-05-17 16:13:23 +02:00
|
|
|
case PTRACE_GETEVENTMSG:
|
|
|
|
/*
|
|
|
|
* Only PTRACE_EVENT_CLONE is currently supported.
|
|
|
|
*/
|
2019-04-29 16:53:44 +02:00
|
|
|
*(unsigned long*)data = _new_thread_lwpid;
|
2016-05-17 16:13:23 +02:00
|
|
|
return 0;
|
|
|
|
case PTRACE_GETREGSET: request_str = "PTRACE_GETREGSET"; break;
|
|
|
|
}
|
|
|
|
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
warning("ptrace(", request_str, " (", Hex(request), ")) called - not implemented!");
|
2016-05-17 16:13:23 +02:00
|
|
|
|
|
|
|
errno = EINVAL;
|
|
|
|
return -1;
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-04-29 16:53:44 +02:00
|
|
|
extern "C" int vfork()
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
2016-05-17 16:13:23 +02:00
|
|
|
/* create the thread announcement pipe */
|
|
|
|
|
|
|
|
if (pipe(_new_thread_pipe) != 0) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
error("could not create the 'new thread' pipe");
|
2016-05-17 16:13:23 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* extract target filename from config file */
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2019-01-21 10:34:56 +01:00
|
|
|
typedef String<32> Filename;
|
|
|
|
Filename filename { };
|
2016-05-17 16:13:23 +02:00
|
|
|
|
2017-05-29 14:52:24 +02:00
|
|
|
Genode::Attached_rom_dataspace config { *genode_env, "config" };
|
2019-01-21 10:34:56 +01:00
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
try {
|
2019-01-21 10:34:56 +01:00
|
|
|
Xml_node const target = config.xml().sub_node("target");
|
|
|
|
|
|
|
|
if (!target.has_attribute("name")) {
|
|
|
|
error("missing 'name' attribute of '<target>' sub node");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
filename = target.attribute_value("name", Filename());
|
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
} catch (Xml_node::Nonexistent_sub_node) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
error("missing '<target>' sub node");
|
2016-05-17 16:13:23 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* extract target node from config file */
|
2017-05-29 14:52:24 +02:00
|
|
|
Xml_node target_node = config.xml().sub_node("target");
|
2016-05-17 16:13:23 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* preserve the configured amount of memory for gdb_monitor and give the
|
|
|
|
* remainder to the child
|
|
|
|
*/
|
|
|
|
Number_of_bytes preserved_ram_quota = 0;
|
|
|
|
try {
|
2017-05-29 14:52:24 +02:00
|
|
|
Xml_node preserve_node = config.xml().sub_node("preserve");
|
2016-05-17 16:13:23 +02:00
|
|
|
if (preserve_node.attribute("name").has_value("RAM"))
|
2019-01-21 10:34:56 +01:00
|
|
|
preserve_node.attribute("quantum").value(preserved_ram_quota);
|
2016-05-17 16:13:23 +02:00
|
|
|
else
|
|
|
|
throw Xml_node::Exception();
|
|
|
|
} catch (...) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
error("could not find a valid <preserve> config node");
|
2016-05-17 16:13:23 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-01-21 10:34:56 +01:00
|
|
|
Number_of_bytes ram_quota = genode_env->pd().avail_ram().value - preserved_ram_quota;
|
2016-05-17 16:13:23 +02:00
|
|
|
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 21:35:43 +02:00
|
|
|
Cap_quota const avail_cap_quota = genode_env->pd().avail_caps();
|
|
|
|
|
|
|
|
Genode::size_t const preserved_caps = 100;
|
|
|
|
|
|
|
|
if (avail_cap_quota.value < preserved_caps) {
|
|
|
|
error("not enough available caps for preservation of ", preserved_caps);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
Cap_quota const cap_quota { avail_cap_quota.value - preserved_caps };
|
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
/* start the application */
|
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
static Heap alloc(genode_env->ram(), genode_env->rm());
|
|
|
|
|
2019-01-21 10:34:56 +01:00
|
|
|
enum { SIGNAL_EP_STACK_SIZE = 2*1024*sizeof(addr_t) };
|
|
|
|
static Entrypoint signal_ep { *genode_env, SIGNAL_EP_STACK_SIZE,
|
|
|
|
"sig_handler", Affinity::Location() };
|
2016-05-17 16:13:23 +02:00
|
|
|
|
2019-04-29 16:53:44 +02:00
|
|
|
int breakpoint_len = 0;
|
|
|
|
unsigned char const *breakpoint_data =
|
|
|
|
the_target->sw_breakpoint_from_kind(0, &breakpoint_len);
|
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
App_child *child = new (alloc) App_child(*genode_env,
|
|
|
|
alloc,
|
2019-01-21 10:34:56 +01:00
|
|
|
filename.string(),
|
2017-05-08 01:33:40 +02:00
|
|
|
Ram_quota{ram_quota},
|
Capability quota accounting and trading
This patch mirrors the accounting and trading scheme that Genode employs
for physical memory to the accounting of capability allocations.
Capability quotas must now be explicitly assigned to subsystems by
specifying a 'caps=<amount>' attribute to init's start nodes.
Analogously to RAM quotas, cap quotas can be traded between clients and
servers as part of the session protocol. The capability budget of each
component is maintained by the component's corresponding PD session at
core.
At the current stage, the accounting is applied to RPC capabilities,
signal-context capabilities, and dataspace capabilities. Capabilities
that are dynamically allocated via core's CPU and TRACE service are not
yet covered. Also, the capabilities allocated by resource multiplexers
outside of core (like nitpicker) must be accounted by the respective
servers, which is not covered yet.
If a component runs out of capabilities, core's PD service prints a
warning to the log. To observe the consumption of capabilities per
component in detail, the PD service is equipped with a diagnostic
mode, which can be enabled via the 'diag' attribute in the target
node of init's routing rules. E.g., the following route enables the
diagnostic mode for the PD session of the "timer" component:
<default-route>
<service name="PD" unscoped_label="timer">
<parent diag="yes"/>
</service>
...
</default-route>
For subsystems based on a sub-init instance, init can be configured
to report the capability-quota information of its subsystems by
adding the attribute 'child_caps="yes"' to init's '<report>'
config node. Init's own capability quota can be reported by adding
the attribute 'init_caps="yes"'.
Fixes #2398
2017-05-08 21:35:43 +02:00
|
|
|
cap_quota,
|
2019-01-21 10:34:56 +01:00
|
|
|
signal_ep,
|
2019-04-29 16:53:44 +02:00
|
|
|
target_node,
|
|
|
|
_new_thread_pipe[1],
|
|
|
|
breakpoint_len,
|
|
|
|
breakpoint_data);
|
2016-05-17 16:13:23 +02:00
|
|
|
|
|
|
|
_genode_child_resources = child->genode_child_resources();
|
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
static Memory_model memory_model(genode_child_resources().region_map_component(), genode_env->rm());
|
|
|
|
|
|
|
|
_memory_model = &memory_model;
|
|
|
|
|
2017-05-11 20:03:28 +02:00
|
|
|
try { child->start(); }
|
|
|
|
catch (Out_of_caps) { error("out of caps during child startup"); return -1; }
|
|
|
|
catch (Out_of_ram) { error("out of RAM during child startup"); return -1; }
|
|
|
|
catch (Service_denied) { error("service denied during child startup"); return -1; }
|
|
|
|
catch (...) { error("could not start child process"); return -1; }
|
2016-05-17 16:13:23 +02:00
|
|
|
|
|
|
|
return GENODE_MAIN_LWPID;
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
extern "C" int kill(pid_t pid, int sig)
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
2017-01-04 11:38:39 +01:00
|
|
|
Cpu_session_component &csc = genode_child_resources().cpu_session_component();
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2019-04-29 16:53:44 +02:00
|
|
|
if (pid <= 0) pid = GENODE_MAIN_LWPID;
|
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
Thread_capability thread_cap = csc.thread_cap(pid);
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
if (!thread_cap.valid()) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
error(__PRETTY_FUNCTION__, ": "
|
|
|
|
"could not find thread capability for pid ", pid);
|
2016-05-17 16:13:23 +02:00
|
|
|
return -1;
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
2016-05-17 16:13:23 +02:00
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
return csc.send_signal(thread_cap, sig);
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
extern "C" int initial_breakpoint_handler(CORE_ADDR addr)
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
2017-01-04 11:38:39 +01:00
|
|
|
Cpu_session_component &csc = genode_child_resources().cpu_session_component();
|
2019-04-29 16:53:44 +02:00
|
|
|
return csc.handle_initial_breakpoint(_sigtrap_lwpid);
|
2016-05-17 16:13:23 +02:00
|
|
|
}
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
|
2019-04-29 16:53:44 +02:00
|
|
|
void genode_set_initial_breakpoint_at(unsigned long addr)
|
2016-05-17 16:13:23 +02:00
|
|
|
{
|
|
|
|
set_breakpoint_at(addr, initial_breakpoint_handler);
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
void genode_remove_thread(unsigned long lwpid)
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
2019-04-29 16:53:44 +02:00
|
|
|
struct thread_info *thread_info =
|
|
|
|
find_thread_ptid(ptid_t(GENODE_MAIN_LWPID, lwpid, 0));
|
|
|
|
struct lwp_info *lwp = get_thread_lwp(thread_info);
|
|
|
|
linux_detach_one_lwp(lwp);
|
2016-05-17 16:13:23 +02:00
|
|
|
}
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
|
2019-04-29 16:53:44 +02:00
|
|
|
void genode_stop_all_threads()
|
2016-05-17 16:13:23 +02:00
|
|
|
{
|
2017-01-04 11:38:39 +01:00
|
|
|
Cpu_session_component &csc = genode_child_resources().cpu_session_component();
|
|
|
|
csc.pause_all_threads();
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
void genode_resume_all_threads()
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
2017-01-04 11:38:39 +01:00
|
|
|
Cpu_session_component &csc = genode_child_resources().cpu_session_component();
|
|
|
|
csc.resume_all_threads();
|
2016-05-17 16:13:23 +02:00
|
|
|
}
|
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
int genode_detach(int pid)
|
|
|
|
{
|
2011-12-22 16:19:25 +01:00
|
|
|
genode_resume_all_threads();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int genode_kill(int pid)
|
|
|
|
{
|
|
|
|
/* TODO */
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
if (verbose) warning(__func__, " not implemented, just detaching instead...");
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
return genode_detach(pid);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
void genode_continue_thread(unsigned long lwpid, int single_step)
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
2017-01-04 11:38:39 +01:00
|
|
|
Cpu_session_component &csc = genode_child_resources().cpu_session_component();
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2017-01-04 11:38:39 +01:00
|
|
|
Cpu_thread_component *cpu_thread = csc.lookup_cpu_thread(lwpid);
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
if (!cpu_thread) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
error(__func__, ": " "could not find CPU thread object for lwpid ", lwpid);
|
2011-12-22 16:19:25 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
cpu_thread->single_step(single_step);
|
|
|
|
cpu_thread->resume();
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
void genode_fetch_registers(struct regcache *regcache, int regno)
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
2019-04-29 16:53:44 +02:00
|
|
|
const struct regs_info *regs_info = (*the_low_target.regs_info) ();
|
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
unsigned long reg_content = 0;
|
|
|
|
|
|
|
|
if (regno == -1) {
|
2019-04-29 16:53:44 +02:00
|
|
|
for (regno = 0; regno < regs_info->usrregs->num_regs; regno++) {
|
2016-05-17 16:13:23 +02:00
|
|
|
if (genode_fetch_register(regno, ®_content) == 0)
|
|
|
|
supply_register(regcache, regno, ®_content);
|
|
|
|
else
|
|
|
|
supply_register(regcache, regno, 0);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (genode_fetch_register(regno, ®_content) == 0)
|
|
|
|
supply_register(regcache, regno, ®_content);
|
|
|
|
else
|
|
|
|
supply_register(regcache, regno, 0);
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
void genode_store_registers(struct regcache *regcache, int regno)
|
2013-10-24 16:05:31 +02:00
|
|
|
{
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
if (verbose) log(__func__, ": regno=", regno);
|
2014-07-15 19:05:26 +02:00
|
|
|
|
2019-04-29 16:53:44 +02:00
|
|
|
const struct regs_info *regs_info = (*the_low_target.regs_info) ();
|
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
unsigned long reg_content = 0;
|
2014-07-15 19:05:26 +02:00
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
if (regno == -1) {
|
2019-04-29 16:53:44 +02:00
|
|
|
for (regno = 0; regno < regs_info->usrregs->num_regs; regno++) {
|
|
|
|
if ((Genode::size_t)register_size(regcache->tdesc, regno) <=
|
|
|
|
sizeof(reg_content)) {
|
2016-05-17 16:13:23 +02:00
|
|
|
collect_register(regcache, regno, ®_content);
|
|
|
|
genode_store_register(regno, reg_content);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2019-04-29 16:53:44 +02:00
|
|
|
if ((Genode::size_t)register_size(regcache->tdesc, regno) <=
|
|
|
|
sizeof(reg_content)) {
|
2016-05-17 16:13:23 +02:00
|
|
|
collect_register(regcache, regno, ®_content);
|
|
|
|
genode_store_register(regno, reg_content);
|
2014-07-15 19:05:26 +02:00
|
|
|
}
|
|
|
|
}
|
2013-10-24 16:05:31 +02:00
|
|
|
}
|
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
unsigned char genode_read_memory_byte(void *addr)
|
|
|
|
{
|
2017-01-04 11:38:39 +01:00
|
|
|
return memory_model().read(addr);
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-05-17 16:13:23 +02:00
|
|
|
int genode_read_memory(CORE_ADDR memaddr, unsigned char *myaddr, int len)
|
|
|
|
{
|
|
|
|
if (verbose)
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
log(__func__, "(", Hex(memaddr), ", ", myaddr, ", ", len, ")");
|
2016-05-17 16:13:23 +02:00
|
|
|
|
|
|
|
if (myaddr)
|
|
|
|
try {
|
|
|
|
for (int i = 0; i < len; i++)
|
|
|
|
myaddr[i] = genode_read_memory_byte((void*)((unsigned long)memaddr + i));
|
|
|
|
} catch (No_memory_at_address) {
|
|
|
|
return EFAULT;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
void genode_write_memory_byte(void *addr, unsigned char value)
|
|
|
|
{
|
2017-01-04 11:38:39 +01:00
|
|
|
memory_model().write(addr, value);
|
2016-05-17 16:13:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int genode_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
|
|
|
|
{
|
|
|
|
if (verbose)
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
log(__func__, "(", Hex(memaddr), ", ", myaddr, ", ", len, ")");
|
2016-05-17 16:13:23 +02:00
|
|
|
|
|
|
|
if (myaddr && (len > 0)) {
|
|
|
|
if (debug_threads) {
|
|
|
|
/* Dump up to four bytes. */
|
|
|
|
unsigned int val = * (unsigned int *) myaddr;
|
|
|
|
if (len == 1)
|
|
|
|
val = val & 0xff;
|
|
|
|
else if (len == 2)
|
|
|
|
val = val & 0xffff;
|
|
|
|
else if (len == 3)
|
|
|
|
val = val & 0xffffff;
|
|
|
|
fprintf(stderr, "Writing %0*x to 0x%08lx", 2 * ((len < 4) ? len : 4),
|
|
|
|
val, (long)memaddr);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < len; i++)
|
|
|
|
try {
|
|
|
|
genode_write_memory_byte((void*)((unsigned long)memaddr + i), myaddr[i]);
|
|
|
|
} catch (No_memory_at_address) {
|
|
|
|
return EFAULT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|