iT邦幫忙

2021 iThome 鐵人賽

DAY 14
0
Software Development

Port Alpine Linux to open source RISC-V platform系列 第 14

Alpine Linux Porting (一點二?)

今天稍微回頭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的問題了。


上一篇
Alpine Linux Porting (一點一?)
下一篇
Alpine Linux Porting (一點三?)
系列文
Port Alpine Linux to open source RISC-V platform30

尚未有邦友留言

立即登入留言