ETISS 0.8.0
Extendable Translating Instruction Set Simulator (version 0.8.0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
GDBServer.cpp
Go to the documentation of this file.
1
53#include "etiss/CPUCore.h"
56#include "etiss/jit/types.h"
57#include <chrono>
58#include <cstring>
59#include <thread>
60
61using namespace etiss::plugin::gdb;
62
67
68void BreakpointDB::set(etiss::uint64 addr, etiss::uint32 val)
69{
70 if (instrbrkpt_ == 0)
71 {
72 if (val == 0)
73 return;
74 instrbrkpt_ = new etiss::uint32 ***[1 << 16];
75 memset(instrbrkpt_, 0, sizeof(etiss::uint32 * **[1 << 16]));
76 }
77 unsigned a1 = (addr)&0xFFFF;
78 if (instrbrkpt_[a1] == 0)
79 {
80 if (val == 0)
81 return;
82 instrbrkpt_[a1] = new etiss::uint32 **[1 << 16];
83 memset(instrbrkpt_[a1], 0, sizeof(etiss::uint32 * *[1 << 16]));
84 }
85 unsigned a2 = (addr >> 16) & 0xFFFF;
86 if (instrbrkpt_[a1][a2] == 0)
87 {
88 if (val == 0)
89 return;
90 instrbrkpt_[a1][a2] = new etiss::uint32 *[1 << 16];
91 memset(instrbrkpt_[a1][a2], 0, sizeof(etiss::uint32 * [1 << 16]));
92 }
93 unsigned a3 = (addr >> 32) & 0xFFFF;
94 if (instrbrkpt_[a1][a2][a3] == 0)
95 {
96 if (val == 0)
97 return;
98 instrbrkpt_[a1][a2][a3] = new etiss::uint32[1 << 16];
99 memset(instrbrkpt_[a1][a2][a3], 0, sizeof(etiss::uint32[1 << 16]));
100 }
101 unsigned a4 = (addr >> 48) & 0xFFFF;
102 instrbrkpt_[a1][a2][a3][a4] = val;
103 if (val == 0)
104 { // cleanup
105 bool empty = true;
106 for (unsigned i = 0; i < (1 << 16); i++)
107 {
108 if (instrbrkpt_[a1][a2][a3][i] != 0)
109 {
110 empty = false;
111 break;
112 }
113 }
114 if (!empty)
115 return;
116 delete instrbrkpt_[a1][a2][a3];
117 instrbrkpt_[a1][a2][a3] = 0;
118 for (unsigned i = 0; i < (1 << 16); i++)
119 {
120 if (instrbrkpt_[a1][a2][i] != 0)
121 {
122 empty = false;
123 break;
124 }
125 }
126 if (!empty)
127 return;
128 delete instrbrkpt_[a1][a2];
129 instrbrkpt_[a1][a2] = 0;
130 for (unsigned i = 0; i < (1 << 16); i++)
131 {
132 if (instrbrkpt_[a1][i] != 0)
133 {
134 empty = false;
135 break;
136 }
137 }
138 if (!empty)
139 return;
140 delete instrbrkpt_[a1];
141 instrbrkpt_[a1] = 0;
142 for (unsigned i = 0; i < (1 << 16); i++)
143 {
144 if (instrbrkpt_[i] != 0)
145 {
146 empty = false;
147 break;
148 }
149 }
150 if (!empty)
151 return;
152 delete instrbrkpt_;
153 instrbrkpt_ = 0;
154 }
155}
156
158{
159 status_paused_ = true;
160 gdb_status_paused_ = true;
161 status_step_ = false;
162 status_pending_jump_ = false;
163 status_pending_kill_ = false;
164 status_jumpaddr_ = false;
165 arch_ = nullptr;
166 cpu_ = nullptr;
167 system_ = nullptr;
171}
172
174{
175 // check for instruction breakpoints
177 {
179 if (unlikely(bp != 0))
180 {
182 {
183 status_paused_ = true;
184 }
185 }
186 }
187 // apply single step pause
188 if (unlikely(status_step_ > 0))
189 {
190 status_paused_ = true;
191 status_step_--;
192 }
194 {
195 return RETURNCODE::CPUTERMINATED;
196 }
197 // check paused state (due to singlestep,ctrl+c)
199 {
201 { // answer pending 'c'/'s' command
202 // std::cout << "GDB: answer: " << "T"<<hex::fromByte(5) << std::endl;
203 con_.snd("T" + hex::fromByte(5), false);
204 gdb_status_paused_ = true;
205 }
206
207 while (unlikely(status_paused_))
208 {
209 handlePacket(true);
211 {
212 return RETURNCODE::CPUTERMINATED;
213 }
215 {
217 status_pending_jump_ = false;
218 }
219 }
220 }
221
222 return RETURNCODE::NOERROR;
223}
224
225etiss::int32 Server::execute()
226{
227
229 {
230 return RETURNCODE::CPUTERMINATED;
231 }
232
234 { // connections such as tcp sockets have a large overhead. to provide acceptable performance packet checks may not
235 // be performed too frequent
237 // check for BREAK event in between blocks
238 handlePacket(false);
239 }
241 {
242 return RETURNCODE::CPUTERMINATED;
243 }
244
245 return 0;
246}
247
248static void Server_finalizeInstrSet(etiss::instr::InstructionSet *set, std::string pcode)
249{
250 if (set == nullptr)
251 return;
252 set->foreach ([pcode](etiss::instr::Instruction &instr) {
253 instr.addCallback(
256 cp.code() = std::string("{\n"
257 "\tetiss_int32 _gdb_exception = gdb_pre_instruction(cpu,system,") +
258 pcode +
259 ");\n"
260 "\tif (_gdb_exception != 0)\n\t return _gdb_exception==-16?0:_gdb_exception;\n"
261 "}";
262 return true;
263 },
264 0);
266 });
267}
268
270{
271 std::string pcode = getPointerCode();
273 vis.foreach ([pcode](etiss::instr::InstructionSet &set) { Server_finalizeInstrSet(&set, pcode); });
274 });
275}
276
278{
279
280 cb.fileglobalCode().insert("extern etiss_int32 gdb_pre_instruction(ETISS_CPU * ,ETISS_System * ,void * );extern "
281 "void gdb_pre_instruction_noreturn(ETISS_CPU * ,ETISS_System * ,void * );");
282}
283
284void Server::handlePacket(bool block)
285{
286
287 if (con_.available(block))
288 {
289 bool isnotification;
290 std::string command = con_.rcv(isnotification);
291 if (command.length() > 0)
292 {
293 if (!status_paused_)
294 {
296 { // answer pending 'c'/'s' command
297 // std::cout << "GDB: answer: " << "T"<<hex::fromByte(5) << std::endl;
298 con_.snd("T" + hex::fromByte(5), false);
299 gdb_status_paused_ = true;
300 }
301 status_paused_ = true;
302 }
303 bool nodbgaction = false;
304 std::string answer;
305 bool answerisnotification = false;
306 switch (command[0])
307 {
308 case 'g': // read registers
309 {
310 for (unsigned i = 0; i < arch_->getGDBCore().mappedRegisterCount(); i++)
311 {
312 std::string regname = arch_->getGDBCore().mapRegister(i);
313 auto f = plugin_core_->getStruct()->findName(regname);
314 if (!f)
315 {
316 answer = "EFF";
317 etiss::log(etiss::ERROR, "Faulty implementation of the GDBCore: Register not found", regname,
318 *plugin_core_);
319 break;
320 }
321 switch (f->width_)
322 {
323 case 1:
324 hex::fromInt(answer, (uint8_t)f->read(), arch_->getGDBCore().isLittleEndian());
325 break;
326 case 2:
327 hex::fromInt(answer, (uint16_t)f->read(), arch_->getGDBCore().isLittleEndian());
328 break;
329 case 4:
330 hex::fromInt(answer, (uint32_t)f->read(), arch_->getGDBCore().isLittleEndian());
331 break;
332 case 8:
333 hex::fromInt(answer, (uint64_t)f->read(), arch_->getGDBCore().isLittleEndian());
334 break;
335 default:
336 answer = "EFF";
337 etiss::log(etiss::ERROR, "GDB g: Invalid read length");
338 }
339 }
340 }
341 break;
342 case 'G': // write registers
343 {
344 size_t treglen = 0;
345 for (unsigned i = 0; i < arch_->getGDBCore().mappedRegisterCount(); i++)
346 {
347 auto f = plugin_core_->getStruct()->findName(arch_->getGDBCore().mapRegister(i));
348 if (!f)
349 {
350 answer = "EFF";
351 etiss::log(etiss::ERROR, "Faulty implementation of the GDBCore: Register not found",
353 break;
354 }
355 treglen += f->width_;
356 }
357 if (command.length() == (treglen * 2) + 1)
358 {
359 answer = "OK";
360 size_t off = 1;
361 for (unsigned i = 0; i < arch_->getGDBCore().mappedRegisterCount(); i++)
362 {
363 std::string regname = arch_->getGDBCore().mapRegister(i);
364 auto f = plugin_core_->getStruct()->findName(regname);
365 if (!f)
366 {
367 answer = "EFF";
368 etiss::log(etiss::ERROR, "Faulty implementation of the GDBCore: Register not found",
369 regname, *plugin_core_);
370 break;
371 }
372 switch (f->width_)
373 {
374 case 1:
375 f->write(hex::toInt<uint8_t>(command, arch_->getGDBCore().isLittleEndian(), off));
376 break;
377 case 2:
378 f->write(hex::toInt<uint16_t>(command, arch_->getGDBCore().isLittleEndian(), off));
379 break;
380 case 4:
381 f->write(hex::toInt<uint32_t>(command, arch_->getGDBCore().isLittleEndian(), off));
382 break;
383 case 8:
384 f->write(hex::toInt<uint64_t>(command, arch_->getGDBCore().isLittleEndian(), off));
385 break;
386 default:
387 answer = "EFF";
388 etiss::log(etiss::ERROR, "GDB G: Invalid write length");
389 }
390 off += f->width_ * 2;
391 }
392 }
393 else
394 {
395 answer = "E11";
396 }
397 }
398 break;
399 case 'P': // write a register
400 {
401 size_t off = 1;
402 unsigned regIndex = 0;
403 std::string valToWrite;
404 if (command.length() > 1)
405 {
406 for (size_t i = 1; i < command.length(); ++i)
407 {
408 if (command[i] == '=' && command.length() > i + 1)
409 {
410 valToWrite = command.substr(i + 1);
411 break;
412 }
413 regIndex = (regIndex << 4) | hex::fromHex(command[i]);
414 answer = "OK";
415 }
416 }
417 auto f = plugin_core_->getStruct()->findName(arch_->getGDBCore().mapRegister(regIndex));
418 if (!f)
419 {
420 answer = "EFF";
421 etiss::log(etiss::ERROR, "Faulty implementation of the GDBCore: Register not found",
423 break;
424 }
425 switch (f->width_)
426 {
427 case 1:
428 f->write(hex::toInt<uint8_t>(valToWrite, arch_->getGDBCore().isLittleEndian(), off));
429 break;
430 case 2:
431 f->write(hex::toInt<uint16_t>(valToWrite, arch_->getGDBCore().isLittleEndian(), off));
432 break;
433 case 4:
434 f->write(hex::toInt<uint32_t>(valToWrite, arch_->getGDBCore().isLittleEndian(), off));
435 break;
436 case 8:
437 f->write(hex::toInt<uint64_t>(valToWrite, arch_->getGDBCore().isLittleEndian(), off));
438 break;
439 default:
440 answer = "EFF";
441 etiss::log(etiss::ERROR, "GDB P: Invalid write length");
442 }
443 off += f->width_ * 2;
444 }
445 break;
446 case 'p': // read a register
447 {
448 unsigned regIndex = 0;
449 if (command.length() > 1)
450 {
451 for (size_t i = 1; i < command.length(); ++i)
452 {
453 regIndex = (regIndex << 4) | hex::fromHex(command[i]);
454 }
455 }
456 auto f = plugin_core_->getStruct()->findName(arch_->getGDBCore().mapRegister(regIndex));
457 if (!f)
458 {
459 answer = "EFF";
460 etiss::log(etiss::ERROR, "Faulty implementation of the GDBCore: Register not found",
462 break;
463 }
464 switch (f->width_)
465 {
466 case 1:
467 hex::fromInt(answer, (uint8_t)f->read(), arch_->getGDBCore().isLittleEndian());
468 break;
469 case 2:
470 hex::fromInt(answer, (uint16_t)f->read(), arch_->getGDBCore().isLittleEndian());
471 break;
472 case 4:
473 hex::fromInt(answer, (uint32_t)f->read(), arch_->getGDBCore().isLittleEndian());
474 break;
475 case 8:
476 hex::fromInt(answer, (uint64_t)f->read(), arch_->getGDBCore().isLittleEndian());
477 break;
478 default:
479 answer = "EFF";
480 etiss::log(etiss::ERROR, "GDB p: Invalid read length");
481 }
482 }
483 break;
484 case 'm': // read memory
485 {
486 unsigned pos = 1;
487 etiss::uint64 addr = hex::tryInt<etiss::uint64>(command, pos);
488 pos++;
489 etiss::uint32 length = hex::tryInt<etiss::uint32>(command, pos);
490 etiss::uint8 *buf = new etiss::uint8[length];
491 etiss::int32 exception = (*system_->dbg_read)(system_->handle, addr, buf, length);
492 if (exception != RETURNCODE::NOERROR)
493 {
494 answer = "EFF";
495 }
496 else
497 {
498 answer = hex::fromBytes(buf, length);
499 }
500 delete[] buf;
501 }
502 break;
503 case 'M': // writes memory
504 {
505 unsigned pos = 1;
506 etiss::uint64 addr = hex::tryInt<etiss::uint64>(command, pos);
507 pos++; // comma
508 etiss::uint32 length = hex::tryInt<etiss::uint32>(command, pos);
509 pos++; // colon
510 std::vector<etiss::uint8> buf(length);
511 for (etiss::uint32 i = 0; i < length; i++)
512 {
513 buf[i] = hex::tryInt<etiss::uint8>(command, pos);
514 }
515 etiss::int32 exception = (*system_->dbg_write)(system_->handle, addr, buf.data(), length);
516 if (exception != RETURNCODE::NOERROR)
517 {
518 answer = "EFF";
519 }
520 else
521 {
522 answer = "OK";
523 }
524 }
525 break;
526 case 'c': // continue
527 {
528 if (command.length() > 1)
529 {
530 etiss::uint64 addr = 0;
531 for (size_t i = 1; i < command.length(); i += 2)
532 {
533 addr = (addr << 8) | hex::toByte(command[i], command[i + 1]);
534 }
535 status_jumpaddr_ = addr;
537 }
538 status_paused_ = false;
539 gdb_status_paused_ = false;
540 status_step_ = 0;
541 // std::cout << "GDB: command: " << command << std::endl;
542 return;
543 }
544 break;
545 case 's':
546 {
547 if (command.length() > 1)
548 {
549 etiss::uint64 addr = 0;
550 for (size_t i = 1; i < command.length(); i += 2)
551 {
552 addr = (addr << 8) | hex::toByte(command[i], command[i + 1]);
553 }
554 status_jumpaddr_ = addr;
556 }
557 status_paused_ = false;
558 gdb_status_paused_ = false;
559 status_step_ = 1;
560 // std::cout << "GDB: command: " << command << std::endl;
561 return;
562 }
563 case '?':
564 {
565 answer = "T";
566 hex::fromByte(answer, 5);
567 }
568 break;
569 case 'v':
570 break;
571 case 'W': // custom break message; might be changed in future if W is used (apply changes also to
572 // Connection::BREAKMESSAGE)
573 {
574 status_paused_ = true;
575 return;
576 }
577 break;
578 case 'Z': // insert breakpoint
579 {
580 if (command.length() > 2 && command[2] == ',')
581 {
582 BreakpointDB *bpDB = nullptr;
583 etiss::uint32 requestedFlags = 0;
584 switch (command[1])
585 {
586 case '0':
587 bpDB = &breakpoints_;
588 requestedFlags = BreakpointDB::BPTYPE_BREAK_MEM;
589 break;
590 case '1':
591 bpDB = &breakpoints_;
592 requestedFlags = BreakpointDB::BPTYPE_BREAK_HW;
593 break;
594 case '2':
595 bpDB = &watchpoints_;
596 requestedFlags = BreakpointDB::BPTYPE_WATCH_WRITE;
597 break;
598 case '3':
599 bpDB = &watchpoints_;
600 requestedFlags = BreakpointDB::BPTYPE_WATCH_READ;
601 break;
602 case '4':
603 bpDB = &watchpoints_;
605 break;
606 }
607 if (bpDB)
608 {
609 unsigned pos = 3;
610 etiss::uint64 addr = hex::tryInt<etiss::uint64>(command, pos);
611 if (pos > 3)
612 {
613 if (bpDB == &breakpoints_)
614 {
615 addr = addr >> minimal_pc_alignment;
616 }
617 etiss::uint32 existingFlags = bpDB->get(addr);
618 if ((existingFlags & requestedFlags) != requestedFlags)
619 {
620 bpDB->set(addr, existingFlags | requestedFlags);
621 }
622 answer = "OK";
623 }
624 else
625 {
626 answer = "EFF";
627 }
628 }
629 }
630 }
631 break;
632 case 'z': // remove breakpoint
633 {
634 if (command.length() > 2 && command[2] == ',')
635 {
636 BreakpointDB *bpDB = nullptr;
637 etiss::uint32 flagsToDelete = 0;
638 switch (command[1])
639 {
640 case '0':
641 bpDB = &breakpoints_;
642 flagsToDelete = BreakpointDB::BPTYPE_BREAK_MEM;
643 break;
644 case '1':
645 bpDB = &breakpoints_;
646 flagsToDelete = BreakpointDB::BPTYPE_BREAK_HW;
647 break;
648 case '2':
649 bpDB = &watchpoints_;
650 flagsToDelete = BreakpointDB::BPTYPE_WATCH_WRITE;
651 break;
652 case '3':
653 bpDB = &watchpoints_;
654 flagsToDelete = BreakpointDB::BPTYPE_WATCH_READ;
655 break;
656 case '4':
657 bpDB = &watchpoints_;
659 break;
660 }
661
662 if (bpDB)
663 {
664 unsigned pos = 3;
665 etiss::uint64 addr = hex::tryInt<etiss::uint64>(command, pos);
666 addr = addr >> minimal_pc_alignment;
667 if (pos > 3)
668 {
669 etiss::uint32 existingFlags = bpDB->get(addr);
670 if ((existingFlags & flagsToDelete) != 0)
671 {
672 bpDB->set(addr, existingFlags & ~flagsToDelete);
673 }
674 answer = "OK";
675 }
676 else
677 {
678 answer = "EFF";
679 }
680 }
681 }
682 }
683 break;
684 case 'q':
685 {
686 if (command.substr(1, 9) == "Supported")
687 {
688 answer = "";
689 }
690 else if (command.substr(1, 8) == "Attached")
691 {
692 answer = "0";
693 }
694 else if (command.substr(1, 8) == "Symbol::")
695 {
696 answer = "OK";
697 }
698 else if (command.substr(1, 1) == "C")
699 {
700 answer = "0";
701 }
702 else if (command.substr(1, 7) == "TStatus")
703 {
704 answer = "T0;tnotrun:0";
705 }
706 else if (command.substr(1, 11) == "fThreadInfo")
707 {
708 answer = "m1";
709 }
710 else if (command.substr(1, 11) == "sThreadInfo")
711 {
712 answer = "l";
713 }
714 }
715 break;
716 case 'k':
717 {
719 return;
720 }
721 break;
722 case 'H':
723 if (command.length() > 1)
724 {
725 switch (command[1])
726 {
727 case 'c':
728 case 'g':
729 answer = "OK"; // only one thread. ignore thread selection and continue
730 break;
731 default:
732 std::cout << "GDB: unknown command: " << command << std::endl;
733 }
734 }
735 else
736 {
737 // std::cout << "GDB: unknown command: " << command << std::endl;
738 }
739 break;
740 default:
741 std::cout << "GDB: unknown command: " << command << std::endl;
742 break;
743 }
744 if (!nodbgaction)
745 {
746 // std::cout << "GDB: command: " << command << std::endl;
747 // std::cout << "GDB: answer: "<<answer << std::endl;
748 }
749 con_.snd(answer, answerisnotification);
750 }
751 }
752}
753
754void Server::preDReadCallback(etiss::uint64 addr)
755{
756 if (!watchpoints_.isEmpty())
757 {
759 {
760 status_paused_ = true;
761 }
762 }
763}
764void Server::preDWriteCallback(etiss::uint64 addr)
765{
766 if (!watchpoints_.isEmpty())
767 {
769 {
770 status_paused_ = true;
771 }
772 }
773}
774
775etiss::int32 Server::postMemAccessCallback(etiss::int32 exception)
776{
777 if (exception)
778 {
779 status_paused_ = true;
780 }
781
782 if (status_paused_)
783 {
785 {
786 con_.snd("T" + hex::fromByte(5), false);
787 gdb_status_paused_ = true;
788 }
789
790 while (unlikely(status_paused_))
791 {
792 handlePacket(true);
794 {
795 return RETURNCODE::CPUTERMINATED;
796 }
798 {
800 status_pending_jump_ = false;
801 exception = RETURNCODE::NOERROR;
802 }
803 }
804 }
805
806 return exception;
807}
808
809std::string Server::_getPluginName() const
810{
811 return "gdbserver";
812}
813
815{
816 return (void *)this;
817}
818
820{
821 arch_ = arch;
822 cpu_ = cpu;
823 system_ = system;
824}
825
827{
828 arch_ = nullptr;
829 cpu_ = nullptr;
830 system_ = nullptr;
831}
832
833Server *Server::createTCPServer(std::map<std::string, std::string> options)
834{
835 int port = 2222;
836
837 { // parse port
838 auto f = options.find("plugin.gdbserver.port");
839 if (f != options.end())
840 {
841 int tmp = atoi(f->second.c_str());
842 if (tmp > 0)
843 port = tmp;
844 else
846 std::string("etiss::plugin::gdb::Server: failed to parse port value for tcp socket: ") +
847 f->second);
848 }
849 }
850
851 Server *s = createTCPServer(port);
852
853 { // parse skip count
854 auto f = options.find("skipcount");
855 if (f != options.end())
856 {
857 int tmp = atoi(f->second.c_str());
858 if (tmp >= 0)
859 s->execute_skip_count = tmp;
860 }
861 }
862
863 { // parse Minimal pc alignment
864
865 auto f = options.find("minPcAlign");
866 if (f != options.end())
867 {
868 int tmp = atoi(f->second.c_str());
869 if (tmp >= 0)
870 s->minimal_pc_alignment = tmp;
871 }
872 }
873 return s;
874}
876{
877
878#if ETISS_USE_POSIX_SOCKET
880 std::string("etiss::plugin::gdb::Server: starting tcp server on port ") + etiss::toString(port));
881
882 std::shared_ptr<Connection> cs(new etiss::plugin::gdb::UnixTCPGDBConnection(port));
883
884 Server *s = new Server(cs.get()->getPacketProtocol());
885
886 s->cinst_ = cs;
887
888 return s;
889#else
890
891 return 0;
892
893#endif
894}
895
896extern "C"
897{
899 {
900 return ((etiss::plugin::gdb::Server *)gdbserver)->preInstructionCallback();
901 }
903 {
905 ((etiss::plugin::gdb::Server *)gdbserver)->preInstructionCallback();
906 }
907}
ETISS_PLUGIN_EXPORT etiss::CPUArch std::map< std::string, std::string > options
create new instance of the CPUArch type at index
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)
__DEVICE__ void * memset(void *__a, int __b, size_t __c)
__device__ __2f16 float bool s
static __inline__ uint32_t
Definition arm_cde.h:25
static __inline__ uint64_t
Definition arm_cde.h:31
static __inline__ uint8_t
Definition arm_mve.h:323
static __inline__ uint16_t
Definition arm_mve.h:315
#define unlikely(x)
Definition types.h:74
int32_t etiss_int32
Definition types.h:92
the interface to translate instructions of and processor architecture
Definition CPUArch.h:162
virtual etiss::plugin::gdb::GDBCore & getGDBCore()
returns arch dependent gdb functions.
Definition CPUArch.cpp:145
virtual std::shared_ptr< VirtualStruct > getStruct()
Get the virtual structure of this CPUCore instance.
Definition CPUCore.h:170
A list of CodeSets.
Definition CodePart.h:570
std::set< std::string > & fileglobalCode()
Definition CodePart.h:604
Contains a small code snipped.
Definition CodePart.h:386
@ PREINITIALDEBUGRETURNING
Definition CodePart.h:397
std::string & code()
Definition CodePart.h:416
A set of CodeParts.
Definition CodePart.h:437
CodePart & prepend(CodePart::TYPE type)
Definition CodePart.h:503
CPUCore * plugin_core_
holds a pointer to the associated CPUCore instance.
Definition Plugin.h:200
std::string getPointerCode() const
returns a C code expression that allows to get or assign a pointer to the variable assigned to this t...
Definition Plugin.cpp:101
stores a bit vector
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
Definition GDBServer.h:80
etiss::uint32 **** instrbrkpt_
important: index maps are reversed to instruction pointer e.g pointer(0x0102030405060708) [POINTER !...
Definition GDBServer.h:117
void set(etiss::uint64 addr, etiss::uint32 val)
Definition GDBServer.cpp:68
etiss::uint32 get(etiss::uint64 addr)
Definition GDBServer.h:92
virtual etiss::uint64 getInstructionPointer(ETISS_CPU *cpu)
allows to calculate the index of the instruction to be executed for breakpoint checks.
Definition GDBCore.cpp:74
virtual std::string mapRegister(unsigned index)
the returned string identifies the register at the given index as defined by gdb.
Definition GDBCore.cpp:58
virtual bool isLittleEndian()
returns true if the values are expected to be little endian
Definition GDBCore.cpp:70
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
Definition GDBServer.h:125
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_
Definition GDBServer.h:158
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)...
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
void preDWriteCallback(etiss::uint64 addr)
void handlePacket(bool block)
static Server * createTCPServer(std::map< std::string, std::string > options)
etiss::uint64 status_jumpaddr_
Definition GDBServer.h:168
void preDReadCallback(etiss::uint64 addr)
etiss::int32 preInstructionCallback()
uint8_t toByte(char h, char l)
converts 2 hex characters to a byte
Definition Hex.cpp:95
std::string fromByte(uint8_t byte)
converts a byte to a hex string (without "0x" prefix);
Definition Hex.cpp:100
std::string fromBytes(uint8_t *buf, size_t length)
converts a sequence of bytes to a representing hex string (without "0x" prefix)
Definition Hex.cpp:114
uint8_t fromHex(char c)
convert a character to the hex value it represents(0-15)
Definition Hex.cpp:56
void fromInt(std::string &string, INT val, bool isLittleEndian)
converts an integer type variable to a hexadecimal representation with the given endianness
Definition Hex.h:131
std::string toString(const T &val)
conversion of type T to std::string.
Definition Misc.h:174
@ VERBOSE
Definition Misc.h:130
@ ERROR
Definition Misc.h:127
void log(Verbosity level, std::string msg)
write log message at the given level.
Definition Misc.cpp:125
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.
Definition CPU.h:89
etiss_uint64 instructionPointer
pointer to next instruction.
Definition CPU.h:92
memory access and time synchronization functions.
Definition System.h:78
void * handle
custom handle that will be passed to the functions of this structure
Definition System.h:116
etiss_int32(* dbg_write)(void *handle, etiss_uint64 addr, etiss_uint8 *buffer, etiss_uint32 length)
direct debug write
Definition System.h:108
etiss_int32(* dbg_read)(void *handle, etiss_uint64 addr, etiss_uint8 *buffer, etiss_uint32 length)
direct debug read
Definition System.h:104