@@ -415,7 +415,8 @@ void Machine::setup_linux_system_calls()
415
415
regs.rax = 0 ;
416
416
SYSPRINT (" rt_sigaction(signum=%x, act=0x%lX, oldact=0x%lx) = 0x%llX\n " ,
417
417
sig, g_act, g_oldact, regs.rax );
418
- cpu.set_registers (regs); });
418
+ cpu.set_registers (regs);
419
+ });
419
420
Machine::install_syscall_handler (
420
421
SYS_rt_sigprocmask, [](vCPU& cpu)
421
422
{
@@ -442,28 +443,28 @@ void Machine::setup_linux_system_calls()
442
443
regs.rax = 0 ;
443
444
SYSPRINT (" rt_sigprocmask(how=%x, set=0x%lX, oldset=0x%lx, size=%u) = 0x%llX\n " ,
444
445
how, g_set, g_oldset, size, regs.rax );
445
- cpu.set_registers (regs); });
446
- Machine::install_syscall_handler (
446
+ cpu.set_registers (regs);
447
+ });
448
+ Machine::install_syscall_handler ( // sigaltstack
447
449
SYS_sigaltstack, [](vCPU& cpu)
448
450
{
449
- /* SYS sigaltstack */
450
451
auto & regs = cpu.registers ();
451
-
452
452
if (regs.rdi != 0x0 ) {
453
453
auto & ss = cpu.machine ().signals ().per_thread (cpu.machine ().threads ().gettid ()).stack ;
454
454
cpu.machine ().copy_from_guest (&ss, regs.rdi , sizeof (ss));
455
455
456
456
SYSPRINT (" sigaltstack(altstack SP=0x%lX flags=0x%X size=0x%lX)\n " ,
457
457
ss.ss_sp , ss.ss_flags , ss.ss_size );
458
458
}
459
-
460
459
regs.rax = 0 ;
461
460
SYSPRINT (" sigaltstack(ss=0x%llX, old_ss=0x%llx) = 0x%llX\n " ,
462
461
regs.rdi , regs.rsi , regs.rax );
463
- cpu.set_registers (regs); });
464
- Machine::install_syscall_handler (
462
+ cpu.set_registers (regs);
463
+ });
464
+ Machine::install_syscall_handler ( // ioctl
465
465
SYS_ioctl, [](vCPU& cpu) {
466
466
auto & regs = cpu.registers ();
467
+ [[maybe_unused]] const int fd = cpu.machine ().fds ().translate (regs.rdi );
467
468
switch (regs.rsi ) {
468
469
case 0x5401 : /* TCGETS */
469
470
if (int (regs.rdi ) >= 0 && int (regs.rdi ) < 3 )
@@ -477,8 +478,8 @@ void Machine::setup_linux_system_calls()
477
478
default :
478
479
regs.rax = EINVAL;
479
480
}
480
- SYSPRINT (" ioctl(fd=0x%llX , req=0x%llx) = 0x%llX\n " ,
481
- regs.rdi , regs.rsi , regs.rax );
481
+ SYSPRINT (" ioctl(vfd=%lld fd=%d , req=0x%llx) = 0x%llX\n " ,
482
+ regs.rdi , fd, regs.rsi , regs.rax );
482
483
cpu.set_registers (regs);
483
484
});
484
485
Machine::install_syscall_handler (
@@ -705,9 +706,20 @@ void Machine::setup_linux_system_calls()
705
706
// int socketpair(int domain, int type, int protocol, int sv[2]);
706
707
const uint64_t g_sv = regs.r10 ;
707
708
int sv[2 ] = { 0 , 0 };
708
- cpu.machine ().copy_to_guest (g_sv, sv, sizeof (sv));
709
- regs.rax = 0 ;
710
- SYSPRINT (" socketpair(..., 0x%lX) = %lld\n " , g_sv, regs.rax );
709
+ const int res = socketpair (AF_UNIX, SOCK_STREAM, 0 , sv);
710
+ if (res < 0 )
711
+ {
712
+ regs.rax = -errno;
713
+ }
714
+ else
715
+ {
716
+ sv[0 ] = cpu.machine ().fds ().manage (sv[0 ], true , true );
717
+ sv[1 ] = cpu.machine ().fds ().manage (sv[1 ], true , true );
718
+ cpu.machine ().copy_to_guest (g_sv, sv, sizeof (sv));
719
+ regs.rax = 0 ;
720
+ }
721
+ SYSPRINT (" socketpair(AF_UNIX, SOCK_STREAM, 0, 0x%lX) = %lld {%d, %d}\n " ,
722
+ g_sv, regs.rax , sv[0 ], sv[1 ]);
711
723
cpu.set_registers (regs);
712
724
});
713
725
Machine::install_syscall_handler (
@@ -757,7 +769,7 @@ void Machine::setup_linux_system_calls()
757
769
} catch (...) {
758
770
regs.rax = -EBADF;
759
771
}
760
- SYSPRINT (" recvfrom(fd=%lld , buf=0x%llX, size=%llu) = %lld\n " ,
772
+ SYSPRINT (" recvfrom(fd=%d , buf=0x%llX, size=%llu) = %lld\n " ,
761
773
vfd, g_buf, bytes, regs.rax );
762
774
cpu.set_registers (regs);
763
775
});
@@ -792,6 +804,12 @@ void Machine::setup_linux_system_calls()
792
804
// const int flags = fcntl(fd, cmd);
793
805
regs.rax = 0x1 ;
794
806
}
807
+ else if (cmd == F_DUPFD_CLOEXEC)
808
+ {
809
+ const int new_fd = dup (fd);
810
+ const int new_vfd = cpu.machine ().fds ().manage (new_fd, false , false );
811
+ regs.rax = new_vfd;
812
+ }
795
813
} catch (...) {
796
814
regs.rax = -EBADF;
797
815
}
@@ -1103,8 +1121,17 @@ void Machine::setup_linux_system_calls()
1103
1121
{
1104
1122
/* SYS epoll_create1 */
1105
1123
auto & regs = cpu.registers ();
1106
- regs.rax = 0 ;
1107
- SYSPRINT (" epoll_create1(...) = %lld\n " , regs.rax );
1124
+ const int fd = epoll_create1 (0 );
1125
+ if (fd < 0 )
1126
+ {
1127
+ regs.rax = -errno;
1128
+ }
1129
+ else
1130
+ {
1131
+ const int vfd = cpu.machine ().fds ().manage (fd, false );
1132
+ regs.rax = vfd;
1133
+ }
1134
+ SYSPRINT (" epoll_create1() = %d (%lld)\n " , fd, regs.rax );
1108
1135
cpu.set_registers (regs);
1109
1136
});
1110
1137
Machine::install_syscall_handler (
@@ -1116,35 +1143,63 @@ void Machine::setup_linux_system_calls()
1116
1143
SYSPRINT (" nanosleep(...) = %lld\n " , regs.rax );
1117
1144
cpu.set_registers (regs);
1118
1145
});
1119
- Machine::install_syscall_handler (
1120
- SYS_epoll_ctl, [](vCPU& cpu) // epoll_ctl
1146
+ Machine::install_syscall_handler ( // epoll_ctl
1147
+ SYS_epoll_ctl, [](vCPU& cpu)
1121
1148
{
1122
1149
auto & regs = cpu.registers ();
1150
+ const int epollfd = cpu.machine ().fds ().translate (regs.rdi );
1151
+ const int op = regs.rsi ;
1152
+ const int fd = cpu.machine ().fds ().translate (regs.rdx );
1123
1153
const uint64_t g_event = regs.r10 ;
1124
1154
struct epoll_event event;
1125
1155
cpu.machine ().copy_from_guest (&event, g_event, sizeof (event));
1126
- regs.rax = 0 ;
1127
- SYSPRINT (" epoll_ctl(fd=%d op=%d event=0x%llX event u64=0x%llX) = %lld\n " ,
1128
- int (regs.rdi ), int (regs.rsi ), event.events , event.data .u64 , regs.rax );
1156
+ if (epoll_ctl (epollfd, op, fd, &event) < 0 ) {
1157
+ regs.rax = -errno;
1158
+ }
1159
+ else {
1160
+ regs.rax = 0 ;
1161
+ }
1162
+ SYSPRINT (" epoll_ctl(epollfd=%d (%lld), op=%d, fd=%d (%lld), g_event=0x%lX) = %lld\n " ,
1163
+ epollfd, regs.rdi , op, fd, regs.rdx , g_event, regs.rax );
1129
1164
cpu.set_registers (regs);
1130
1165
});
1131
- Machine::install_syscall_handler (
1132
- SYS_epoll_wait, [](vCPU& cpu) // epoll_wait
1166
+ Machine::install_syscall_handler ( // epoll_wait
1167
+ SYS_epoll_wait, [](vCPU& cpu)
1133
1168
{
1134
1169
auto & regs = cpu.registers ();
1135
1170
const int vfd = regs.rdi ;
1136
1171
[[maybe_unused]] const uint64_t g_events = regs.rsi ;
1137
1172
[[maybe_unused]] const int maxevents = regs.rdx ;
1138
1173
[[maybe_unused]] const int timeout = regs.r10 ;
1139
- // Create fake event
1140
- struct epoll_event event;
1141
- event.events = EPOLLIN;
1142
- event.data .fd = 1 ;
1143
- cpu.machine ().copy_to_guest (regs.rsi , &event, sizeof (event));
1144
- regs.rax = 1 ;
1174
+ if (maxevents > 1024 )
1175
+ {
1176
+ regs.rax = -EINVAL;
1177
+ SYSPRINT (" epoll_wait(fd=%d maxevents=%d timeout=%d) = %lld\n " ,
1178
+ vfd, maxevents, timeout, regs.rax );
1179
+ cpu.set_registers (regs);
1180
+ return ;
1181
+ }
1182
+ std::array<struct epoll_event , 1024 > guest_events;
1183
+ const int epollfd = cpu.machine ().fds ().translate (vfd);
1184
+ const int result =
1185
+ epoll_wait (epollfd, guest_events.data (), maxevents, timeout);
1186
+ // Copy events back to guest
1187
+ if (result > 0 )
1188
+ {
1189
+ cpu.machine ().copy_to_guest (g_events, guest_events.data (),
1190
+ result * sizeof (struct epoll_event ));
1191
+ } else if (result < 0 )
1192
+ {
1193
+ regs.rax = -errno;
1194
+ }
1195
+ else
1196
+ {
1197
+ regs.rax = 0 ;
1198
+ // XXX: This is a giga hack.
1199
+ cpu.machine ().threads ().suspend_and_yield ();
1200
+ }
1145
1201
SYSPRINT (" epoll_wait(...) = %lld\n " , regs.rax );
1146
1202
cpu.set_registers (regs);
1147
- // cpu.machine().threads().suspend_and_yield();
1148
1203
});
1149
1204
Machine::install_syscall_handler (
1150
1205
SYS_getrlimit, [](vCPU& cpu) { // getrlimit
@@ -1171,7 +1226,7 @@ void Machine::setup_linux_system_calls()
1171
1226
struct rlimit64 lim{};
1172
1227
lim.rlim_cur = 4UL << 20 ;
1173
1228
lim.rlim_max = 4UL << 20 ;
1174
- SYSPRINT (" prlimit64: current stack limit 0x%llX max 0x%llX \n " ,
1229
+ SYSPRINT (" prlimit64: current stack limit 0x%lX max 0x%lX \n " ,
1175
1230
lim.rlim_cur , lim.rlim_max );
1176
1231
cpu.machine ().copy_to_guest (oldptr, &lim, sizeof (lim));
1177
1232
}
@@ -1180,7 +1235,7 @@ void Machine::setup_linux_system_calls()
1180
1235
#ifdef VERBOSE_SYSCALLS
1181
1236
struct rlimit64 lim {};
1182
1237
cpu.machine ().copy_from_guest (&lim, newptr, sizeof (lim));
1183
- SYSPRINT (" prlimit64: new stack limit 0x%llX max 0x%llX \n " ,
1238
+ SYSPRINT (" prlimit64: new stack limit 0x%lX max 0x%lX \n " ,
1184
1239
lim.rlim_cur , lim.rlim_max );
1185
1240
#endif
1186
1241
}
@@ -1192,7 +1247,7 @@ void Machine::setup_linux_system_calls()
1192
1247
struct rlimit64 lim{};
1193
1248
lim.rlim_cur = 4096 ;
1194
1249
lim.rlim_max = 4096 ;
1195
- SYSPRINT (" prlimit64: current nofile limit 0x%llX max 0x%llX \n " ,
1250
+ SYSPRINT (" prlimit64: current nofile limit 0x%lX max 0x%lX \n " ,
1196
1251
lim.rlim_cur , lim.rlim_max );
1197
1252
cpu.machine ().copy_to_guest (oldptr, &lim, sizeof (lim));
1198
1253
}
0 commit comments