Skip to content

Commit

Permalink
Merge pull request #1479 from Sonicadvance1/fix_msqid_ds
Browse files Browse the repository at this point in the history
Linux: Finish 32-bit msqid_ds usage
  • Loading branch information
Sonicadvance1 authored Dec 29, 2021
2 parents 1d5bd15 + 3d1cef4 commit 98210fd
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 6 deletions.
5 changes: 4 additions & 1 deletion Source/Tests/LinuxSyscalls/Syscalls/Msg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ namespace FEX::HLE {
SYSCALL_ERRNO();
});

// XXX: msqid_ds is definitely not correct for 32-bit
REGISTER_SYSCALL_IMPL_PASS(msgctl, [](FEXCore::Core::CpuStateFrame *Frame, int msqid, int cmd, struct msqid_ds *buf) -> uint64_t {
// A quirk of this syscall
// On 32-bit this syscall ONLY supports IPC_64 msqid_ds encoding
// If an application want to use the old style encoding then it needs to use the ipc syscall with MSGCTL command
// ipc syscall supports both IPC_64 and old encoding
uint64_t Result = ::msgctl(msqid, cmd, buf);
SYSCALL_ERRNO();
});
Expand Down
16 changes: 11 additions & 5 deletions Source/Tests/LinuxSyscalls/x32/Semaphore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ namespace FEX::HLE::x32 {
int32_t cmd = third & 0xFF;
compat_ptr<semun_32> semun(ptr);
bool IPC64 = third & 0x100;
#define UNHANDLED(x) case x: LOGMAN_MSG_A_FMT("Unhandled semctl cmd: " #x); break
switch (cmd) {
case IPC_SET: {
struct semid_ds buf{};
Expand Down Expand Up @@ -172,7 +171,6 @@ namespace FEX::HLE::x32 {
LOGMAN_MSG_A_FMT("Unhandled semctl cmd: {}", cmd);
return -EINVAL;
}
#undef UNHANDLED
break;
}
case OP_SEMTIMEDOP: {
Expand Down Expand Up @@ -237,9 +235,18 @@ namespace FEX::HLE::x32 {
msgun_32 msgun{};
msgun.val = ptr;
bool IPC64 = second & 0x100;
#define UNHANDLED(x) case x: LOGMAN_MSG_A_FMT("Unhandled msgctl cmd: " #x); break
switch (cmd) {
UNHANDLED(IPC_SET);
case IPC_SET: {
struct msqid_ds buf{};
if (IPC64) {
buf = *msgun.buf64;
}
else {
buf = *msgun.buf32;
}
Result = ::msgctl(msqid, cmd, &buf);
break;
}
case MSG_STAT:
case MSG_STAT_ANY:
case IPC_STAT: {
Expand Down Expand Up @@ -271,7 +278,6 @@ namespace FEX::HLE::x32 {
LOGMAN_MSG_A_FMT("Unhandled msgctl cmd: {}", cmd);
return -EINVAL;
}
#undef UNHANDLED
break;
}
case OP_SHMAT: {
Expand Down
39 changes: 39 additions & 0 deletions Source/Tests/LinuxSyscalls/x32/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1557,6 +1557,22 @@ struct msqid_ds_32 {
uint16_t msg_lrpid;

msqid_ds_32() = delete;
operator struct msqid_ds() const {
struct msqid_ds val{};
// msg_first and msg_last are unused and untouched
val.msg_perm = msg_perm;
val.msg_stime = msg_stime;
val.msg_rtime = msg_rtime;
val.msg_ctime = msg_ctime;

val.msg_cbytes = msg_cbytes;
val.msg_qnum = msg_qnum;
val.msg_qbytes = msg_qbytes;
val.msg_lspid = msg_lspid;
val.msg_lrpid = msg_lrpid;
return val;
}

msqid_ds_32(struct msqid_ds buf)
: msg_perm {buf.msg_perm} {
// msg_first and msg_last are unused and untouched
Expand Down Expand Up @@ -1608,6 +1624,29 @@ struct msqid_ds_64 {
uint32_t _pad[2];

msqid_ds_64() = delete;
operator struct msqid_ds() const {
struct msqid_ds val{};
val.msg_perm = msg_perm;
val.msg_stime = msg_stime_high;
val.msg_stime <<= 32;
val.msg_stime |= msg_stime;

val.msg_rtime = msg_rtime_high;
val.msg_rtime <<= 32;
val.msg_rtime |= msg_rtime;

val.msg_ctime = msg_ctime_high;
val.msg_ctime <<= 32;
val.msg_ctime |= msg_ctime;

val.msg_cbytes = msg_cbytes;
val.msg_qnum = msg_qnum;
val.msg_qbytes = msg_qbytes;
val.msg_lspid = msg_lspid;
val.msg_lrpid = msg_lrpid;
return val;
}

msqid_ds_64(struct msqid_ds buf)
: msg_perm {buf.msg_perm} {
msg_stime = buf.msg_stime;
Expand Down

0 comments on commit 98210fd

Please sign in to comment.