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