Browse Source

time64: fixed msgctl/semctl/shmctl result errors for for MIPS32/RISCV32

yliu 2 months ago
parent
commit
bf47b6f40a

+ 18 - 2
libc/misc/sysvipc/msgq.c

@@ -1,5 +1,6 @@
 #include <errno.h>
 #include <sys/msg.h>
+#include <stddef.h>
 #include "ipc.h"
 #ifdef __UCLIBC_HAS_THREADS_NATIVE__
 #include "sysdep-cancel.h"
@@ -7,6 +8,12 @@
 #define SINGLE_THREAD_P 1
 #endif
 
+#if defined(__UCLIBC_USE_TIME64__)
+union msqun {
+    struct msqid_ds* buff;
+    void *__pad;
+};
+#endif
 
 #ifdef L_msgctl
 
@@ -18,9 +25,18 @@ static __inline__ _syscall3(int, __libc_msgctl, int, msqid, int, cmd, struct msq
 int msgctl(int msqid, int cmd, struct msqid_ds *buf)
 {
 #ifdef __NR_msgctl
-	return __libc_msgctl(msqid, cmd | __IPC_64, buf);
+	int __ret = __libc_msgctl(msqid, cmd | __IPC_64, buf);
+#if (__WORDSIZE == 32) && defined(__UCLIBC_USE_TIME64__) && (defined(__MIPSEL__) || defined(__riscv))
+	union msqun arg = {.buff = buf};
+	if (arg.__pad != NULL) {
+		arg.buff->msg_stime = (__time_t)arg.buff->msg_stime_internal_1 | (__time_t)(arg.buff->msg_stime_internal_2) << 32;
+		arg.buff->msg_rtime = (__time_t)arg.buff->msg_rtime_internal_1 | (__time_t)(arg.buff->msg_rtime_internal_2) << 32;
+		arg.buff->msg_ctime = (__time_t)arg.buff->msg_ctime_internal_1 | (__time_t)(arg.buff->msg_ctime_internal_2) << 32;
+	}
+#endif
+	return __ret;
 #else
-    return __syscall_ipc(IPCOP_msgctl, msqid, cmd | __IPC_64, 0, buf, 0);
+	return __syscall_ipc(IPCOP_msgctl, msqid, cmd | __IPC_64, 0, buf, 0);
 #endif
 }
 #endif

+ 4 - 2
libc/misc/sysvipc/sem.c

@@ -58,8 +58,10 @@ int semctl(int semid, int semnum, int cmd, ...)
 #ifdef __NR_semctl
     int __ret = __semctl(semid, semnum, cmd | __IPC_64, arg.__pad);
 #if defined(__UCLIBC_USE_TIME64__)
-    arg.buf->sem_otime = (__time_t)arg.buf->__sem_otime_internal_1 | (__time_t)(arg.buf->__sem_otime_internal_2) << 32;
-    arg.buf->sem_ctime = (__time_t)arg.buf->__sem_ctime_internal_1 | (__time_t)(arg.buf->__sem_ctime_internal_2) << 32;
+    if (arg.__pad != NULL) {
+        arg.buf->sem_otime = (__time_t)arg.buf->__sem_otime_internal_1 | (__time_t)(arg.buf->__sem_otime_internal_2) << 32;
+        arg.buf->sem_ctime = (__time_t)arg.buf->__sem_ctime_internal_1 | (__time_t)(arg.buf->__sem_ctime_internal_2) << 32;
+    }
 #endif
     return __ret;
 #else

+ 17 - 1
libc/misc/sysvipc/shm.c

@@ -25,6 +25,13 @@
 #include <syscall.h>
 #include "ipc.h"
 
+#if defined(__UCLIBC_USE_TIME64__)
+union shmun {
+    struct shmid_ds* buff;
+    void *__pad;
+};
+#endif
+
 #ifdef L_shmat
 /* Attach the shared memory segment associated with SHMID to the data
    segment of the calling process.  SHMADDR and SHMFLG determine how
@@ -59,7 +66,16 @@ static __always_inline _syscall3(int, __syscall_shmctl, int, shmid, int, cmd, st
 int shmctl(int shmid, int cmd, struct shmid_ds *buf)
 {
 #ifdef __NR_shmctl
-	return __syscall_shmctl(shmid, cmd | __IPC_64, buf);
+	int __ret = __syscall_shmctl(shmid, cmd | __IPC_64, buf);
+#if (__WORDSIZE == 32) && defined(__MIPSEL__) && defined(__UCLIBC_USE_TIME64__)
+	union shmun arg = {.buff = buf};
+        if (arg.__pad != NULL) {
+		arg.buff->shm_atime = (__time_t)arg.buff->shm_atime_internal_1 | (__time_t)(arg.buff->shm_atime_internal_2) << 32;
+		arg.buff->shm_dtime = (__time_t)arg.buff->shm_dtime_internal_1 | (__time_t)(arg.buff->shm_dtime_internal_2) << 32;
+		arg.buff->shm_ctime = (__time_t)arg.buff->shm_ctime_internal_1 | (__time_t)(arg.buff->shm_ctime_internal_2) << 32;
+	}
+#endif
+	return __ret;
 #else
     return __syscall_ipc(IPCOP_shmctl, shmid, cmd | __IPC_64, 0, buf, 0);
 #endif

+ 14 - 0
libc/sysdeps/linux/common/bits/msq.h

@@ -37,17 +37,31 @@ typedef unsigned long int msglen_t;
 struct msqid_ds
 {
   struct ipc_perm msg_perm;	/* structure describing operation permission */
+#if (__WORDSIZE == 32 && defined(__riscv) && defined(__UCLIBC_USE_TIME64__))
+  unsigned long int msg_stime_internal_1;
+  unsigned long int msg_stime_internal_2;
+  unsigned long int msg_rtime_internal_1;
+  unsigned long int msg_rtime_internal_2;
+  unsigned long int msg_ctime_internal_1;
+  unsigned long int msg_ctime_internal_2;
+#else
   __time_t msg_stime;		/* time of last msgsnd command */
   unsigned long int __uclibc_unused1;
   __time_t msg_rtime;		/* time of last msgrcv command */
   unsigned long int __uclibc_unused2;
   __time_t msg_ctime;		/* time of last change */
   unsigned long int __uclibc_unused3;
+#endif
   unsigned long int __msg_cbytes; /* current number of bytes on queue */
   msgqnum_t msg_qnum;		/* number of messages currently on queue */
   msglen_t msg_qbytes;		/* max number of bytes allowed on queue */
   __pid_t msg_lspid;		/* pid of last msgsnd() */
   __pid_t msg_lrpid;		/* pid of last msgrcv() */
+#if (__WORDSIZE == 32 && defined(__riscv) && defined(__UCLIBC_USE_TIME64__))
+  __time_t msg_stime;		/* time of last msgsnd command */
+  __time_t msg_rtime;		/* time of last msgrcv command */
+  __time_t msg_ctime;		/* time of last change */
+#endif
   unsigned long int __uclibc_unused4;
   unsigned long int __uclibc_unused5;
 };

+ 4 - 4
libc/sysdeps/linux/common/bits/sem.h

@@ -45,8 +45,8 @@ struct semid_ds
 #else
   __time_t sem_otime;			/* last semop() time */
 #endif
-#if (__WORDSIZE == 32 && !defined(__ARC64_ARCH32__) && !defined(__arc__) && !defined(__arm__) && !defined(__or1k__) && !defined(__xtensa__)) || \
-    ((defined(__ARC64_ARCH32__) || defined(__arc__) || defined(__arm__) || defined(__or1k__) || defined(__xtensa__)) && !defined(__UCLIBC_USE_TIME64__))
+#if (__WORDSIZE == 32 && !defined(__ARC64_ARCH32__) && !defined(__arc__) && !defined(__arm__) && !defined(__or1k__) && !defined(__xtensa__) && !defined(__riscv)) || \
+    ((defined(__ARC64_ARCH32__) || defined(__arc__) || defined(__arm__) || defined(__or1k__) || defined(__xtensa__) || defined(__riscv)) && !defined(__UCLIBC_USE_TIME64__))
   unsigned long int __uclibc_unused1;
 #endif
 #if defined(__UCLIBC_USE_TIME64__)
@@ -55,8 +55,8 @@ struct semid_ds
 #else
   __time_t sem_ctime;			/* last time changed by semctl() */
 #endif
-#if (__WORDSIZE == 32 && !defined(__ARC64_ARCH32__) && !defined(__arc__) && !defined(__arm__) && !defined(__or1k__) && !defined(__xtensa__)) || \
-    ((defined(__ARC64_ARCH32__) || defined(__arc__) || defined(__arm__) || defined(__or1k__) || defined(__xtensa__)) && !defined(__UCLIBC_USE_TIME64__))
+#if (__WORDSIZE == 32 && !defined(__ARC64_ARCH32__) && !defined(__arc__) && !defined(__arm__) && !defined(__or1k__) && !defined(__xtensa__) && !defined(__riscv)) || \
+    ((defined(__ARC64_ARCH32__) || defined(__arc__) || defined(__arm__) || defined(__or1k__) || defined(__xtensa__) || defined(__riscv)) && !defined(__UCLIBC_USE_TIME64__))
   unsigned long int __uclibc_unused2;
 #endif
   unsigned long int sem_nsems;		/* number of semaphores in set */

+ 20 - 20
libc/sysdeps/linux/mips/bits/msq.h

@@ -35,29 +35,24 @@ typedef unsigned long int msglen_t;
 
 /* Structure of record for one message inside the kernel.
    The type `struct msg' is opaque.  */
+/* Just for (__WORDSIZE == 32) && (__MIPSEL__) */
 struct msqid_ds
 {
   struct ipc_perm msg_perm;	/* structure describing operation permission */
-#if (__WORDSIZE == 32) && !defined(__MIPSEL__)
-	unsigned long	__unused1;
-#endif
-  __time_t msg_stime;		/* time of last msgsnd command */
-#if (__WORDSIZE == 32) && defined(__MIPSEL__)
-	unsigned long	__unused1;
-#endif
-#if (__WORDSIZE == 32) && !defined(__MIPSEL__)
-	unsigned long	__unused2;
-#endif
-  __time_t msg_rtime;		/* time of last msgrcv command */
-#if (__WORDSIZE == 32) && defined(__MIPSEL__)
-	unsigned long	__unused2;
-#endif
-#if (__WORDSIZE == 32) && !defined(__MIPSEL__)
-	unsigned long	__unused3;
-#endif
-  __time_t msg_ctime;		/* time of last change */
-#if (__WORDSIZE == 32) && defined(__MIPSEL__)
-	unsigned long	__unused3;
+#if defined(__UCLIBC_USE_TIME64__)
+  unsigned long msg_stime_internal_1;		/* time of last msgsnd command */
+  unsigned long msg_stime_internal_2;
+  unsigned long msg_rtime_internal_1;		/* time of last msgrcv command */
+  unsigned long msg_rtime_internal_2;
+  unsigned long msg_ctime_internal_1;		/* time of last change */
+  unsigned long msg_ctime_internal_2;
+#else
+  __time_t msg_stime;
+  unsigned long int __uclibc_unused1;
+  __time_t msg_rtime;
+  unsigned long int __uclibc_unused2;
+  __time_t msg_ctime;
+  unsigned long int __uclibc_unused3;
 #endif
   unsigned long int __msg_cbytes; /* current number of bytes on queue */
   msgqnum_t msg_qnum;		/* number of messages currently on queue */
@@ -66,6 +61,11 @@ struct msqid_ds
   __pid_t msg_lrpid;		/* pid of last msgrcv() */
   unsigned long int __uclibc_unused4;
   unsigned long int __uclibc_unused5;
+#if defined(__UCLIBC_USE_TIME64__)
+  __time_t msg_stime;
+  __time_t msg_rtime;
+  __time_t msg_ctime;
+#endif
 };
 
 #ifdef __USE_MISC

+ 4 - 3
libc/sysdeps/linux/mips/bits/sem.h

@@ -40,20 +40,21 @@ struct semid_ds
   struct ipc_perm sem_perm;		/* operation permission struct */
 #if defined(__UCLIBC_USE_TIME64__)
   unsigned long int __sem_otime_internal_1; /* last semop() time */
-  unsigned long int __sem_otime_internal_2;
   unsigned long int __sem_ctime_internal_1; /* last time changed by semctl() */
-  unsigned long int __sem_ctime_internal_2;
 #else
   __time_t sem_otime;                  /* last semop() time */
   __time_t sem_ctime;			/* last time changed by semctl() */
 #endif
   unsigned long int sem_nsems;		/* number of semaphores in set */
 #if defined(__UCLIBC_USE_TIME64__)
+  unsigned long int __sem_otime_internal_2;
+  unsigned long int __sem_ctime_internal_2;
   __time_t sem_otime;
   __time_t sem_ctime;
-#endif
+#else
   unsigned long int __uclibc_unused1;
   unsigned long int __uclibc_unused2;
+#endif
 };
 
 /* The user should define a union like the following to use it for arguments

+ 23 - 5
libc/sysdeps/linux/mips/bits/shm.h

@@ -46,14 +46,32 @@ struct shmid_ds
   {
     struct ipc_perm shm_perm;		/* operation permission struct */
     size_t shm_segsz;			/* size of segment in bytes */
-    __time_t shm_atime;			/* time of last shmat() */
-    __time_t shm_dtime;			/* time of last shmdt() */
-    __time_t shm_ctime;			/* time of last change by shmctl() */
+#if defined(__UCLIBC_USE_TIME64__)
+    unsigned long int shm_atime_internal_1;		/* time of last shmat() */
+    unsigned long int shm_dtime_internal_1;		/* time of last shmdt() */
+    unsigned long int shm_ctime_internal_1;		/* time of last change by shmctl() */
+#else
+    __time_t shm_atime;
+    __time_t shm_dtime;
+    __time_t shm_ctime;
+#endif
     __pid_t shm_cpid;			/* pid of creator */
     __pid_t shm_lpid;			/* pid of last shmop */
     shmatt_t shm_nattch;		/* number of current attaches */
-    unsigned long int __uclibc_unused1;
-    unsigned long int __uclibc_unused2;
+#if defined(__UCLIBC_USE_TIME64__)
+    unsigned short int shm_atime_internal_2;		/* time of last shmat() */
+    unsigned short int shm_dtime_internal_2;		/* time of last shmdt() */
+    unsigned short int shm_ctime_internal_2;		/* time of last change by shmctl() */
+    unsigned short int __uclibc_unused1;
+    __time_t shm_atime;
+    __time_t shm_dtime;
+    __time_t shm_ctime;
+#else
+    unsigned short int __uclibc_unused1;
+    unsigned short int __uclibc_unused2;
+    unsigned short int __uclibc_unused3;
+    unsigned short int __uclibc_unused4;
+#endif
   };
 
 #ifdef __USE_MISC

+ 6 - 0
libc/sysdeps/linux/riscv32/bits/shm.h

@@ -37,12 +37,18 @@ struct shmid_ds
   {
     struct ipc_perm shm_perm;		/* operation permission struct */
     size_t shm_segsz;			/* size of segment in bytes */
+#if defined(__UCLIBC_USE_TIME64__)
+    __time_t shm_atime;
+    __time_t shm_dtime;
+    __time_t shm_ctime;
+#else
     __time_t shm_atime;			/* time of last shmat() */
     unsigned long int __uclibc_unused1;
     __time_t shm_dtime;			/* time of last shmdt() */
     unsigned long int __uclibc_unused2;
     __time_t shm_ctime;			/* time of last change by shmctl() */
     unsigned long int __uclibc_unused3;
+#endif
     __pid_t shm_cpid;			/* pid of creator */
     __pid_t shm_lpid;			/* pid of last shmop */
     shmatt_t shm_nattch;		/* number of current attaches */