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