qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: stat64 wrong on sparc64 user


From: Laurent Vivier
Subject: Re: stat64 wrong on sparc64 user
Date: Wed, 29 Mar 2023 18:22:01 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.8.0

Le 28/03/2023 à 14:22, Luca Bonissi a écrit :
On 28/03/23 13:55, Thomas Huth wrote:
On 28/03/2023 13.48, Luca Bonissi wrote:
--- qemu-20230327/linux-user/syscall_defs.h    2023-03-27 15:41:42.000000000 
+0200
+++ qemu-20230327/linux-user/syscall_defs.h.new    2023-03-27 
21:43:25.615115126 +0200
@@ -1450,7 +1450,7 @@ struct target_stat {
      unsigned int    st_dev;
      abi_ulong    st_ino;
      unsigned int    st_mode;
-    unsigned int    st_nlink;
+    short int    st_nlink;
      unsigned int    st_uid;

That looks wrong at a first glance. IIRC Sparc is a very strictly aligned architecture, so if the previous field "st_mode" was aligned to a 4-byte boundary, the "st_uid" field now would not be aligned anymore... are you sure about this change? Maybe it needs a padding field now?

The padding is automatic (either on Sparc or x86-64): short will be aligned to 2-byte boundary, int will be aligned to 4-byte boundary, long will be aligned to 8-byte boundary.

E.g.:
st_dev=0x05060708;
st_ino=0x1112131415161718;
st_mode=0x1a1b1c1d;
st_nlink=0x2728;
st_uid=0x2a2b2c2d;
st_gid=0x3a3b3c3d;
st_rdev=0x35363738;
st_size=0x4142434445464748;
st_blksize=0x5152535455565758;

will result (sparc64 - big endian):
00: 05 06 07 08 00 00 00 00
08: 11 12 13 14 15 16 17 18
10: 1A 1B 1C 1D 27 28 00 00
18: 2A 2B 2C 2D 3A 3B 3C 3D
20: 35 36 37 38 00 00 00 00
28: 41 42 43 44 45 46 47 48
30: 00 00 00 00 00 00 00 00
38: 00 00 00 00 00 00 00 00
40: 00 00 00 00 00 00 00 00
48: 51 52 53 54 55 56 57 58
50: 00 00 00 00 00 00 00 00
58: 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00

Or on x86-64 (little endian):
00: 08 07 06 05 00 00 00 00
08: 18 17 16 15 14 13 12 11
10: 1D 1C 1B 1A 28 27 00 00
18: 2D 2C 2B 2A 3D 3C 3B 3A
20: 38 37 36 35 00 00 00 00
28: 48 47 46 45 44 43 42 41
30: 00 00 00 00 00 00 00 00
38: 00 00 00 00 00 00 00 00
40: 00 00 00 00 00 00 00 00
48: 58 57 56 55 54 53 52 51
50: 00 00 00 00 00 00 00 00
58: 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00

Please note the automatic padding between "st_dev" and "st_ino" (offset 0x04, 4 bytes), "st_nlink" and "st_uid" (offset 0x16, 2 bytes), "st_rdev" and "st_size" (offset 0x24, 4 bytes).

Placing st_nlink as int would result in incorrect big/little endian conversion, so it should be set as short. If you like clearer source code, you can optionally add padding, but it is not mandatory.


To have automatic alignment according to target ABI, you must use abi_XXX type (see include/exec/user/abitypes.h)

For sparc, from the kernel, we have:

struct stat {
        unsigned int st_dev;
        __kernel_ino_t st_ino;
        __kernel_mode_t st_mode;
        short   st_nlink;
        __kernel_uid32_t st_uid;
        __kernel_gid32_t st_gid;
        unsigned int st_rdev;
        long    st_size;
        long    st_atime;
        long    st_mtime;
        long    st_ctime;
        long    st_blksize;
        long    st_blocks;
        unsigned long  __unused4[2];
};

So for the st_link we need to use abi_short.

We can do the same with stat64 and other fields (see 
linux/arch/sparc/include/uapi/asm/stat.h)

Thanks,
Laurent



reply via email to

[Prev in Thread] Current Thread [Next in Thread]