今天稍微回頭update一下musl這邊的porting狀況。
之前遇到message queue跟share memory的部份,後來去對了一下porting的狀況,發現是qemu-riscv32這邊相關的time_t還是使用32bit的:
struct target_shmid_ds {
struct target_ipc_perm shm_perm; /* operation permission struct */
abi_long shm_segsz; /* size of segment in bytes */
abi_ulong shm_atime; /* time of last shmat() */
#if TARGET_ABI_BITS == 32
abi_ulong __unused1;
#endif
abi_ulong shm_dtime; /* time of last shmdt() */
#if TARGET_ABI_BITS == 32
abi_ulong __unused2;
#endif
abi_ulong shm_ctime; /* time of last change by shmctl() */
#if TARGET_ABI_BITS == 32
abi_ulong __unused3;
#endif
abi_int shm_cpid; /* pid of creator */
abi_int shm_lpid; /* pid of last shmop */
abi_ulong shm_nattch; /* number of current attaches */
abi_ulong __unused4;
abi_ulong __unused5;
};
struct target_msqid_ds
{
struct target_ipc_perm msg_perm;
abi_ulong msg_stime;
#if TARGET_ABI_BITS == 32
abi_ulong __unused1;
#endif
abi_ulong msg_rtime;
#if TARGET_ABI_BITS == 32
abi_ulong __unused2;
#endif
abi_ulong msg_ctime;
#if TARGET_ABI_BITS == 32
abi_ulong __unused3;
#endif
abi_ulong __msg_cbytes;
abi_ulong msg_qnum;
abi_ulong msg_qbytes;
abi_ulong msg_lspid;
abi_ulong msg_lrpid;
abi_ulong __unused4;
abi_ulong __unused5;
};
abi_ulong
的意義是指:今天你target的sizeof(ulong)是什麼,他就是什麼,在ilp32上,unsigned long
是32bit寬。
老實說這點在kernel段也算是一個不打算修的漏網之魚:
typedef __kernel_long_t __kernel_time_t;
......
#ifndef __kernel_long_t
typedef long __kernel_long_t;
typedef unsigned long __kernel_ulong_t;
#endif
17 /* Obsolete, used only for backwards compatibility and libc5 compiles */
18 struct msqid_ds {
19 struct ipc_perm msg_perm;
20 struct msg *msg_first; /* first message on queue,unused */
21 struct msg *msg_last; /* last message in queue,unused */
22 __kernel_time_t msg_stime; /* last msgsnd time */
23 __kernel_time_t msg_rtime; /* last msgrcv time */
24 __kernel_time_t msg_ctime; /* last change time */
25 unsigned long msg_lcbytes; /* Reuse junk fields for 32 bit */
26 unsigned long msg_lqbytes; /* ditto */
27 unsigned short msg_cbytes; /* current number of bytes on queue */
28 unsigned short msg_qnum; /* number of messages in queue */
29 unsigned short msg_qbytes; /* max number of bytes on queue */
30 __kernel_ipc_pid_t msg_lspid; /* pid of last msgsnd */
31 __kernel_ipc_pid_t msg_lrpid; /* last receive pid */
32 };
目前kernel看起來是要直接deprecate掉這些票東西了,所以2038問題直接不想解的感覺XD
另外一個是我在bootstrap Alpine Linux 的 openssl
時,發現musl的dlsym變成undefined sysmbol,這點是因為musl libc再做dso的loading時,在32平台上要作time64的rebind :
hidden void *__dlsym_redir_time64(void *restrict p, const char *restrict s, void *restrict ra)
{
#if _REDIR_TIME64
const char *suffix, *suffix2 = "";
char redir[36];
/* Map the symbol name to a time64 version of itself according to the
* pattern used for naming the redirected time64 symbols. */
size_t l = strnlen(s, sizeof redir);
if (l<4 || l==sizeof redir) goto no_redir;
if (s[l-2]=='_' && s[l-1]=='r') {
l -= 2;
suffix2 = s+l;
}
if (l<4) goto no_redir;
if (!strcmp(s+l-4, "time")) suffix = "64";
else suffix = "_time64";
/* Use the presence of the remapped symbol name in libc to determine
* whether it's one that requires time64 redirection; replace if so. */
snprintf(redir, sizeof redir, "__%.*s%s%s", (int)l, s, suffix, suffix2);
if (find_sym(&ldso, redir, 1).sym) s = redir;
no_redir:
#endif
return __dlsym(p, s, ra);
}
為了這件事情,我們必須仿造其他平台新增檔案 src/ldso/riscv32/dlsym_time64.S
:
#define __dlsym __dlsym_redir_time64
#define dlsym __dlsym_time64
#include "dlsym.s"
作為這件事情,重新rebuild & repack Alpine Linux的musl-*.apk
,就可以順利打掉包含openssl等等package會build fail的問題了。