145 lines
4.0 KiB
C++
145 lines
4.0 KiB
C++
/*
|
|
* \brief Cpu_thread_component class for GDB monitor
|
|
* \author Christian Prochaska
|
|
* \date 2016-05-12
|
|
*/
|
|
|
|
/*
|
|
* 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 Affero General Public License version 3.
|
|
*/
|
|
|
|
#ifndef _CPU_THREAD_COMPONENT_H_
|
|
#define _CPU_THREAD_COMPONENT_H_
|
|
|
|
/* Genode includes */
|
|
#include <base/thread.h>
|
|
#include <cpu_session/cpu_session.h>
|
|
#include <cpu_thread/client.h>
|
|
|
|
#include "config.h"
|
|
#include "append_list.h"
|
|
#include "cpu_session_component.h"
|
|
|
|
extern "C" int delete_gdb_breakpoint_at(long long where);
|
|
|
|
namespace Gdb_monitor { class Cpu_thread_component; }
|
|
|
|
class Gdb_monitor::Cpu_thread_component : public Rpc_object<Cpu_thread>,
|
|
public Append_list<Cpu_thread_component>::Element
|
|
{
|
|
private:
|
|
|
|
static constexpr bool _verbose = false;
|
|
|
|
Cpu_session_component &_cpu_session_component;
|
|
Cpu_thread_client _parent_cpu_thread;
|
|
int const _new_thread_pipe_write_end;
|
|
int const _breakpoint_len;
|
|
unsigned char const *_breakpoint_data;
|
|
|
|
unsigned long _lwpid { 0 };
|
|
addr_t _initial_ip { 0 };
|
|
|
|
/*
|
|
* SIGTRAP, SIGSTOP and SIGINT must get delivered to the gdbserver code
|
|
* in the same order that they were generated. Since these signals are
|
|
* generated by different threads, the signal ep is used as
|
|
* synchronization point.
|
|
*/
|
|
Signal_handler<Cpu_thread_component> _exception_handler;
|
|
Signal_handler<Cpu_thread_component> _sigstop_handler;
|
|
Signal_handler<Cpu_thread_component> _sigint_handler;
|
|
|
|
int _pipefd[2];
|
|
bool _initial_sigtrap_pending = true;
|
|
bool _initial_breakpoint_handled = false;
|
|
|
|
/* data for breakpoint at first instruction */
|
|
enum { MAX_BREAKPOINT_LEN = 8 }; /* value from mem-break.c */
|
|
unsigned char _original_instructions[MAX_BREAKPOINT_LEN];
|
|
addr_t _breakpoint_ip;
|
|
|
|
bool _set_breakpoint_at_first_instruction(addr_t ip);
|
|
void _remove_breakpoint_at_first_instruction();
|
|
|
|
void _handle_exception();
|
|
void _handle_sigstop();
|
|
void _handle_sigint();
|
|
|
|
public:
|
|
|
|
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,
|
|
int const new_thread_pipe_write_end,
|
|
int const breakpoint_len,
|
|
unsigned char const *breakpoint_data);
|
|
|
|
~Cpu_thread_component();
|
|
|
|
Signal_context_capability exception_signal_context_cap()
|
|
{
|
|
return _exception_handler;
|
|
}
|
|
|
|
Signal_context_capability sigstop_signal_context_cap()
|
|
{
|
|
return _sigstop_handler;
|
|
}
|
|
|
|
Signal_context_capability sigint_signal_context_cap()
|
|
{
|
|
return _sigint_handler;
|
|
}
|
|
|
|
Thread_capability thread_cap() { return cap(); }
|
|
unsigned long lwpid() { return _lwpid; }
|
|
|
|
Thread_capability parent_thread_cap()
|
|
{
|
|
return _parent_cpu_thread.rpc_cap();
|
|
}
|
|
|
|
int signal_pipe_read_fd() { return _pipefd[0]; }
|
|
|
|
int handle_initial_breakpoint()
|
|
{
|
|
if (!_initial_breakpoint_handled) {
|
|
_initial_breakpoint_handled = true;
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int send_signal(int signo);
|
|
|
|
int deliver_signal(int signo);
|
|
|
|
/**************************
|
|
** CPU thread interface **
|
|
*************************/
|
|
|
|
Dataspace_capability utcb() override;
|
|
void start(addr_t, addr_t) override;
|
|
void pause() override;
|
|
void resume() override;
|
|
void single_step(bool) override;
|
|
void cancel_blocking() override;
|
|
Thread_state state() override;
|
|
void state(Thread_state const &) override;
|
|
void exception_sigh(Signal_context_capability) override;
|
|
void affinity(Affinity::Location) override;
|
|
unsigned trace_control_index() override;
|
|
Dataspace_capability trace_buffer() override;
|
|
Dataspace_capability trace_policy() override;
|
|
};
|
|
|
|
#endif /* _CPU_THREAD_COMPONENT_H_ */
|