11#include " rsp_client.hpp"
22
3- #include < sys/types.h >
4- #include < sys/socket.h >
5- #include < sys/select .h>
3+ #include < cstdarg >
4+ #include < cstring >
5+ #include < fcntl .h>
66#include < linux/kvm.h>
77#include < netinet/in.h>
88#include < netinet/tcp.h>
9- #include < unistd.h>
10- #include < cstdarg>
11- #include < cstring>
129#include < stdexcept>
10+ #include < sys/types.h>
11+ #include < sys/socket.h>
12+ #include < sys/select.h>
13+ #include < sys/stat.h>
14+ #include < unistd.h>
1315#include " amd64/memory_layout.hpp"
1416
1517/* *
1820
1921namespace tinykvm {
2022
21- RSP::RSP (vCPU& cpu, uint16_t port)
22- : m_cpu{cpu}
23+ RSP::RSP (const std::string& filename, vCPU& cpu, uint16_t port)
24+ : m_cpu{cpu}, m_filename{filename}
2325{
2426 this ->server_fd = socket (AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0 );
2527
@@ -45,8 +47,8 @@ RSP::RSP(vCPU& cpu, uint16_t port)
4547 /* We need to make sure the VM can be stepped through */
4648 m_cpu.machine ().stop (false );
4749}
48- RSP::RSP (Machine& machine, uint16_t port)
49- : RSP(machine.cpu(), port)
50+ RSP::RSP (const std::string& filename, Machine& machine, uint16_t port)
51+ : RSP(filename, machine.cpu(), port)
5052{}
5153std::unique_ptr<RSPClient> RSP::accept (int timeout_secs)
5254{
@@ -85,14 +87,14 @@ std::unique_ptr<RSPClient> RSP::accept(int timeout_secs)
8587 close (sockfd);
8688 return nullptr ;
8789 }
88- return std::make_unique<RSPClient>(m_cpu, sockfd);
90+ return std::make_unique<RSPClient>(m_filename, m_cpu, sockfd);
8991}
9092RSP::~RSP () {
9193 close (server_fd);
9294}
9395
94- RSPClient::RSPClient (vCPU& cpu, int fd)
95- : m_cpu{&cpu}, sockfd(fd) {}
96+ RSPClient::RSPClient (const std::string& filename, vCPU& cpu, int fd)
97+ : m_cpu{&cpu}, sockfd(fd), m_filename{filename} {}
9698RSPClient::~RSPClient () {
9799 if (!is_closed ())
98100 close (this ->sockfd );
@@ -267,11 +269,11 @@ void RSPClient::handle_query()
267269{
268270 if (strncmp (" qSupported" , buffer.data (), strlen (" qSupported" )) == 0 )
269271 {
270- sendf (" PacketSize=%x;swbreak-;hwbreak+" , PACKET_SIZE);
272+ sendf (" PacketSize=%x;swbreak-;hwbreak+;qXfer:libraries:read+; " , PACKET_SIZE);
271273 }
272274 else if (strncmp (" qAttached" , buffer.data (), strlen (" qC" )) == 0 )
273275 {
274- send (" 1 " );
276+ send (" 0 " );
275277 }
276278 else if (strncmp (" qC" , buffer.data (), strlen (" qC" )) == 0 )
277279 {
@@ -281,7 +283,14 @@ void RSPClient::handle_query()
281283 else if (strncmp (" qOffsets" , buffer.data (), strlen (" qOffsets" )) == 0 )
282284 {
283285 // Section relocation offsets
284- send (" Text=0;Data=0;Bss=0" );
286+ uint64_t offset = 0x0 ;
287+ for (const auto & mapping : machine ().main_memory ().mmap_ranges ) {
288+ if (mapping.filename == this ->m_filename ) {
289+ offset = mapping.virtbase ;
290+ break ;
291+ }
292+ }
293+ sendf (" TextSeg=%lx" , offset);
285294 }
286295 else if (strncmp (" qfThreadInfo" , buffer.data (), strlen (" qfThreadInfo" )) == 0 )
287296 {
@@ -407,7 +416,115 @@ void RSPClient::handle_executing()
407416 {
408417 send (" " );
409418 }
419+ else if (strncmp (" vFile:setfs" , buffer.data (), strlen (" vFile:setfs" )) == 0 )
420+ {
421+ send (" " );
422+ }
410423 else {
424+ // Check for file operations
425+ if (strncmp (" vFile:open" , buffer.data (), strlen (" vFile:open" )) == 0 )
426+ {
427+ // vFile:open:filename,flags,mode
428+ char filename[512 ];
429+ int flags = 0 , mode = 0 ;
430+ int ret = sscanf (buffer.c_str (), " vFile:open:%511[^,],%d,%o" ,
431+ filename, &flags, &mode);
432+ if (ret == 3 ) {
433+ printf (" Opening file: %s (flags=%d, mode=%o)\n " ,
434+ filename, flags, mode);
435+ // NOTE: We are not doing any sandboxing here!
436+ int fd = open (filename, flags, mode);
437+ if (fd < 0 ) {
438+ send (" " );
439+ return ;
440+ } else {
441+ sendf (" F%d" , fd);
442+ }
443+ } else {
444+ send (" F01" );
445+ }
446+ return ;
447+ }
448+ else if (strncmp (" vFile:pread" , buffer.data (), strlen (" vFile:pread" )) == 0 )
449+ {
450+ // vFile:pread:fd,buf,bufsize,offset
451+ int fd = 0 ;
452+ uint32_t bufsize = 0 ;
453+ uint64_t offset = 0 ;
454+ int ret = sscanf (buffer.c_str (), " vFile:pread:%d,0,%x,%lx" ,
455+ &fd, &bufsize, &offset);
456+ if (ret == 3 && bufsize < 4096 ) {
457+ char data[4096 ];
458+ ssize_t rlen = pread (fd, data, bufsize, offset);
459+ if (rlen < 0 ) {
460+ sendf (" F%02x" , -errno);
461+ return ;
462+ }
463+ char out[8192 + 1 ];
464+ char * d = out;
465+ for (ssize_t i = 0 ; i < rlen; i++) {
466+ uint8_t val = data[i];
467+ *d++ = lut[(val >> 4 ) & 0xF ];
468+ *d++ = lut[(val >> 0 ) & 0xF ];
469+ }
470+ *d++ = 0 ;
471+ sendf (" F00;%s" , out);
472+ } else {
473+ send (" F01" );
474+ }
475+ return ;
476+ }
477+ else if (strncmp (" vFile:close" , buffer.data (), strlen (" vFile:close" )) == 0 )
478+ {
479+ // vFile:close:fd
480+ int fd = 0 ;
481+ int ret = sscanf (buffer.c_str (), " vFile:close:%d" , &fd);
482+ if (ret == 1 ) {
483+ int r = close (fd);
484+ if (r < 0 )
485+ r = -errno;
486+ sendf (" F%02x" , r);
487+ } else {
488+ send (" F01" );
489+ }
490+ return ;
491+ }
492+ else if (strncmp (" vFile:fstat" , buffer.data (), strlen (" vFile:fstat" )) == 0 )
493+ {
494+ // vFile:fstat:fd
495+ int fd = 0 ;
496+ int ret = sscanf (buffer.c_str (), " vFile:fstat:%d" , &fd);
497+ if (ret == 1 ) {
498+ struct stat st;
499+ int r = fstat (fd, &st);
500+ if (r < 0 ) {
501+ sendf (" F%02x" , -errno);
502+ return ;
503+ }
504+ sendf (" F00;0%llo,0%llo,0%llo,0%llo,0%llo,0%llo,0%llo,0%llo,0%llo,0%llo,0%llo,0%llo,0%llo,0%llo,0%llo,0%llo" ,
505+ (__u64)st.st_dev ,
506+ (__u64)st.st_ino ,
507+ (__u64)st.st_mode ,
508+ (__u64)st.st_nlink ,
509+ (__u64)st.st_uid ,
510+ (__u64)st.st_gid ,
511+ (__u64)st.st_rdev ,
512+ (__u64)st.st_size ,
513+ (__u64)st.st_blksize ,
514+ (__u64)st.st_blocks ,
515+ (__u64)st.st_atim .tv_sec ,
516+ (__u64)st.st_atim .tv_nsec ,
517+ (__u64)st.st_mtim .tv_sec ,
518+ (__u64)st.st_mtim .tv_nsec ,
519+ (__u64)st.st_ctim .tv_sec ,
520+ (__u64)st.st_ctim .tv_nsec
521+ );
522+ } else {
523+ send (" F01" );
524+ }
525+ return ;
526+ }
527+ // Unknown v packet
411528 if (UNLIKELY (m_verbose)) {
412529 fprintf (stderr, " Unknown executor: %s\n " ,
413530 buffer.data ());
0 commit comments