21#include "etiss/jit/types.h"
22#include "etiss/jit/ReturnCode.h"
43 unsigned a1 = (addr) & 0xFFFF;
51 unsigned a2 = (addr >> 16) & 0xFFFF;
59 unsigned a3 = (addr >> 32) & 0xFFFF;
64 instrbrkpt_[a1][a2][a3] =
new etiss::uint32[1 << 16];
67 unsigned a4 = (addr >> 48) & 0xFFFF;
72 for (
unsigned i = 0; i < (1 << 16); i++)
84 for (
unsigned i = 0; i < (1 << 16); i++)
96 for (
unsigned i = 0; i < (1 << 16); i++)
108 for (
unsigned i = 0; i < (1 << 16); i++)
161 return RETURNCODE::CPUTERMINATED;
178 return RETURNCODE::CPUTERMINATED;
188 return RETURNCODE::NOERROR;
196 return RETURNCODE::CPUTERMINATED;
208 return RETURNCODE::CPUTERMINATED;
225 cp.
code() = std::string(
"{\n"
226 "\tetiss_int32 _gdb_exception = gdb_pre_instruction(cpu,system,") +
229 "\tif (_gdb_exception != 0)\n\t return _gdb_exception==-16?0:_gdb_exception;\n"
249 cb.
fileglobalCode().insert(
"extern etiss_int32 gdb_pre_instruction(ETISS_CPU * ,ETISS_System * ,void * );extern "
250 "void gdb_pre_instruction_noreturn(ETISS_CPU * ,ETISS_System * ,void * );");
259 std::string command =
con_.
rcv(isnotification);
260 if (command.length() > 0)
272 bool nodbgaction =
false;
274 bool answerisnotification =
false;
279 for (
unsigned i = 0; i <
arch_->
getGDBCore().mappedRegisterCount(); i++)
314 for (
unsigned i = 0; i <
arch_->
getGDBCore().mappedRegisterCount(); i++)
324 treglen += f->width_;
326 if (command.length() == (treglen * 2) + 1)
330 for (
unsigned i = 0; i <
arch_->
getGDBCore().mappedRegisterCount(); i++)
359 off += f->width_ * 2;
370 const size_t off = 1;
371 unsigned regIndex = 0;
372 std::string valToWrite;
373 if (command.length() > 1)
375 for (
size_t i = 1; i < command.length(); ++i)
377 if (command[i] ==
'=' && command.length() > i + 1)
379 valToWrite = command.substr(i + 1);
417 unsigned regIndex = 0;
418 if (command.length() > 1)
420 for (
size_t i = 1; i < command.length(); ++i)
548 etiss::uint64 addr = hex::tryInt<etiss::uint64>(command, pos);
550 etiss::uint32
length = hex::tryInt<etiss::uint32>(command, pos);
551 etiss::uint8 *buf =
new etiss::uint8[
length];
553 if (exception != RETURNCODE::NOERROR)
567 etiss::uint64 addr = hex::tryInt<etiss::uint64>(command, pos);
569 etiss::uint32
length = hex::tryInt<etiss::uint32>(command, pos);
571 std::vector<etiss::uint8> buf(
length);
572 for (etiss::uint32 i = 0; i <
length; i++)
574 buf[i] = hex::tryInt<etiss::uint8>(command, pos);
577 if (exception != RETURNCODE::NOERROR)
589 if (command.length() > 1)
591 etiss::uint64 addr = 0;
592 for (
size_t i = 1; i < command.length(); i += 2)
594 addr = (addr << 8) |
hex::toByte(command[i], command[i + 1]);
608 if (command.length() > 1)
610 etiss::uint64 addr = 0;
611 for (
size_t i = 1; i < command.length(); i += 2)
613 addr = (addr << 8) |
hex::toByte(command[i], command[i + 1]);
641 if (command.length() > 2 && command[2] ==
',')
644 etiss::uint32 requestedFlags = 0;
671 etiss::uint64 addr = hex::tryInt<etiss::uint64>(command, pos);
678 etiss::uint32 existingFlags = bpDB->
get(addr);
679 if ((existingFlags & requestedFlags) != requestedFlags)
681 bpDB->
set(addr, existingFlags | requestedFlags);
695 if (command.length() > 2 && command[2] ==
',')
698 etiss::uint32 flagsToDelete = 0;
726 etiss::uint64 addr = hex::tryInt<etiss::uint64>(command, pos);
730 etiss::uint32 existingFlags = bpDB->
get(addr);
731 if ((existingFlags & flagsToDelete) != 0)
733 bpDB->
set(addr, existingFlags & ~flagsToDelete);
747 if (command.substr(1, 9) ==
"Supported")
749 answer =
"PacketSize=8000;qXfer:features:read+;";
751 else if (command.substr(1, 8) ==
"Attached")
755 else if (command.substr(1, 8) ==
"Symbol::")
759 else if (command.substr(1, 1) ==
"C")
763 else if (command.substr(1, 7) ==
"TStatus")
765 answer =
"T0;tnotrun:0";
767 else if (command.substr(1, 11) ==
"fThreadInfo")
771 else if (command.substr(1, 11) ==
"sThreadInfo")
775 else if (command.substr(1, 4) ==
"Xfer")
778 std::string target_reqxml_fname;
781 sscanf(command.c_str(),
"qXfer:features:read:%255[^:]:%x,%x", fname_buf, &target_reqxml_addr,
783 target_reqxml_fname = fname_buf;
784 std::string xml_contents =
786 uint32_t xml_len = xml_contents.length();
787 if (target_reqxml_len >= (xml_len - target_reqxml_addr))
790 answer += xml_contents.substr(target_reqxml_addr, xml_len - target_reqxml_addr);
795 answer += xml_contents.substr(target_reqxml_addr, target_reqxml_len);
807 if (command.length() > 1)
816 std::cout <<
"GDB: unknown command: " << command << std::endl;
825 std::cout <<
"GDB: unknown command: " << command << std::endl;
833 con_.
snd(answer, answerisnotification);
879 return RETURNCODE::CPUTERMINATED;
885 exception = RETURNCODE::NOERROR;
922 auto f =
options.find(
"plugin.gdbserver.port");
925 int tmp = atoi(f->second.c_str());
930 std::string(
"etiss::plugin::gdb::Server: failed to parse port value for tcp socket: ") +
938 auto f =
options.find(
"skipcount");
941 int tmp = atoi(f->second.c_str());
943 s->execute_skip_count = tmp;
949 auto f =
options.find(
"minPcAlign");
952 int tmp = atoi(f->second.c_str());
954 s->minimal_pc_alignment = tmp;
962#if ETISS_USE_POSIX_SOCKET
964 std::string(
"etiss::plugin::gdb::Server: starting tcp server on port ") +
etiss::toString(port));
966 std::shared_ptr<Connection> cs(
new etiss::plugin::gdb::UnixTCPGDBConnection(port));
ETISS_PLUGIN_EXPORT etiss::CPUArch std::map< std::string, std::string > options
create new instance of the CPUArch type at index
contains neccesary interfaces for instruction translation.
defines main cpu core interface
etiss_int32 gdb_pre_instruction(ETISS_CPU *cpu, ETISS_System *system, void *gdbserver)
static void Server_finalizeInstrSet(etiss::instr::InstructionSet *set, std::string pcode)
void gdb_pre_instruction_noreturn(ETISS_CPU *, ETISS_System *, void *gdbserver)
contains container classes to store instruction definitions + translation functions and build a trans...
__DEVICE__ void * memset(void *__a, int __b, size_t __c)
__device__ __2f16 float bool s
static __inline__ uint32_t
static __inline__ uint64_t
static __inline__ uint8_t
static __inline__ uint16_t
the interface to translate instructions of and processor architecture
virtual etiss::plugin::gdb::GDBCore & getGDBCore()
returns arch dependent gdb functions.
std::string getArchName() const
returns the name of this architecture.
virtual std::shared_ptr< VirtualStruct > getStruct()
Get the virtual structure of this CPUCore instance.
std::set< std::string > & fileglobalCode()
Contains a small code snipped.
@ PREINITIALDEBUGRETURNING
CodePart & prepend(CodePart::TYPE type)
CPUCore * plugin_core_
holds a pointer to the associated CPUCore instance.
std::string getPointerCode() const
returns a C code expression that allows to get or assign a pointer to the variable assigned to this t...
this class contains parameters that persist in between instruction lookpus/translation within a trans...
holds etiss::instr::Instruction instances and handles automatic instruction tree creation.
void foreach(std::function< void(Instruction &)> func)
holds information and translation callbacks for an instruction.
bool addCallback(std::function< bool(BitArray &, etiss::CodeSet &, InstructionContext &)> callback, uint32_t builtinGroups, const std::set< uint32_t > &groups=std::set< uint32_t >())
holds etiss::instr::VariableInstructionSet instances for different modes.
void foreach(std::function< void(VariableInstructionSet &)> call)
holds etiss::instr::InstructionSet instances with different bit widths.
void foreach(std::function< void(InstructionSet &)> func)
structure to store breakpoints
etiss::uint32 **** instrbrkpt_
important: index maps are reversed to instruction pointer e.g pointer(0x0102030405060708) [POINTER !...
void set(etiss::uint64 addr, etiss::uint32 val)
etiss::uint32 get(etiss::uint64 addr)
virtual etiss::uint64 getInstructionPointer(ETISS_CPU *cpu)
allows to calculate the index of the instruction to be executed for breakpoint checks.
virtual std::string mapRegister(unsigned index)
the returned string identifies the register at the given index as defined by gdb.
virtual bool isLittleEndian()
returns true if the values are expected to be little endian
virtual std::string getXMLContents(ETISS_CPU *cpu, std::string archName, std::string fname)
implements gdb's packet protocol
virtual bool snd(std::string answer, bool isnotification)
virtual std::string rcv(bool &isnotification)
virtual bool available(bool block=false)
gdb server implementation that is used as a plugin in etiss
void cleanup() override
this function is called after cpu execution loop (etiss::CPUCore::execute) finished.
etiss::int32 postMemAccessCallback(etiss::int32 exception)
std::string _getPluginName() const override
void * getPluginHandle() override
called to get the handle that is available in translated code via getPoinerCode()....
etiss::int32 execute() override
called before a block and may act in the same way as a block
etiss::plugin::gdb::PacketProtocol & con_
bool status_pending_jump_
void init(ETISS_CPU *cpu, ETISS_System *system, CPUArch *arch) override
this function is called before the plugin is used in the cpu execution loop (etiss::CPUCore::execute)...
unsigned execute_skip_count
BreakpointDB watchpoints_
unsigned execute_skip_index
Server(etiss::plugin::gdb::PacketProtocol &pp)
void finalizeInstrSet(etiss::instr::ModedInstructionSet &) const override
called after all instructions have been added to allow last changes
void finalizeCodeBlock(etiss::CodeBlock &) const override
called after all instructions have been translated for the code block
bool status_pending_kill_
BreakpointDB breakpoints_
void preDWriteCallback(etiss::uint64 addr)
void handlePacket(bool block)
unsigned minimal_pc_alignment
static Server * createTCPServer(std::map< std::string, std::string > options)
etiss::uint64 status_jumpaddr_
void preDReadCallback(etiss::uint64 addr)
etiss::int32 preInstructionCallback()
uint8_t toByte(char h, char l)
converts 2 hex characters to a byte
std::string fromByte(uint8_t byte)
converts a byte to a hex string (without "0x" prefix);
std::string fromBytes(uint8_t *buf, size_t length)
converts a sequence of bytes to a representing hex string (without "0x" prefix)
uint8_t fromHex(char c)
convert a character to the hex value it represents(0-15)
void fromInt(std::string &string, INT val, bool isLittleEndian)
converts an integer type variable to a hexadecimal representation with the given endianness
std::string toString(const T &val)
conversion of type T to std::string.
void log(Verbosity level, std::string msg)
write log message at the given level.
float __ovld __cnfn length(float p)
Return the length of vector p, i.e., sqrt(p.x2 + p.y 2 + ...)
basic cpu state structure needed for execution of any cpu architecture.
etiss_uint64 instructionPointer
pointer to next instruction.
memory access and time synchronization functions.
void * handle
custom handle that will be passed to the functions of this structure
etiss_int32(* dbg_write)(void *handle, etiss_uint64 addr, etiss_uint8 *buffer, etiss_uint32 length)
direct debug write
etiss_int32(* dbg_read)(void *handle, etiss_uint64 addr, etiss_uint8 *buffer, etiss_uint32 length)
direct debug read