Date: Sat, 5 Jan 2019 21:15:51 -0800 From: Mark Millard <marklmi@yahoo.com> To: Kyle Evans <kevans@FreeBSD.org>, freebsd-emulation@freebsd.org, ports-list freebsd <freebsd-ports@freebsd.org> Cc: Sean Bruno <sbruno@freebsd.org>, freebsd-arm <freebsd-arm@freebsd.org> Subject: qemu-arm-static has target_freebsd11_nstat too small vs. arm native's struct nstat Message-ID: <62F581E3-EBB6-4980-BD20-4E121D64BBC5@yahoo.com>
next in thread | raw e-mail | index | archive | help
[The context here is FreeBSD head -r341836 based and ports head -r488859 = based.] Note: I assume that "struct target_shmd_ds" is meant to match the memory = layout of the target's native "struct shmid_ds". Otherwise the reported = differences below could be irrelevant. For armv7 (and likely armv6) the following code: printf("sizeof(struct nstat) =3D %lu\n", (unsigned long) = sizeof(struct nstat)); printf("st_dev %lu\n", (unsigned long) offsetof(struct nstat, = st_dev)); printf("st_ino %lu\n", (unsigned long) offsetof(struct nstat, = st_ino)); printf("st_mode %lu\n", (unsigned long) offsetof(struct nstat, = st_mode)); printf("st_nlink %lu\n", (unsigned long) offsetof(struct nstat, = st_nlink)); printf("st_uid %lu\n", (unsigned long) offsetof(struct nstat, = st_uid)); printf("st_gid %lu\n", (unsigned long) offsetof(struct nstat, = st_gid)); printf("st_rdev %lu\n", (unsigned long) offsetof(struct nstat, = st_rdev)); printf("st_atim %lu\n", (unsigned long) offsetof(struct nstat, = st_atim)); printf("st_mtim %lu\n", (unsigned long) offsetof(struct nstat, = st_mtim)); printf("st_ctim %lu\n", (unsigned long) offsetof(struct nstat, = st_ctim)); printf("st_size %lu\n", (unsigned long) offsetof(struct nstat, = st_size)); printf("st_blocks %lu\n", (unsigned long) offsetof(struct nstat, = st_blocks)); printf("st_blksize %lu\n", (unsigned long) offsetof(struct = nstat, st_blksize)); printf("st_flags %lu\n", (unsigned long) offsetof(struct nstat, = st_flags)); printf("st_gen %lu\n", (unsigned long) offsetof(struct nstat, = st_gen)); printf("st_birthtim %lu\n", (unsigned long) offsetof(struct = nstat, st_birthtim)); produces: sizeof(struct nstat) =3D 128 st_dev 0 st_ino 4 st_mode 8 st_nlink 12 st_uid 16 st_gid 20 st_rdev 24 st_atim 32 st_mtim 48 st_ctim 64 st_size 80 st_blocks 88 st_blksize 96 st_flags 100 st_gen 104 st_birthtim 112 However gdb reports for qemu-arm-static (on amd64): (gdb) p/d sizeof(struct target_freebsd11_nstat) $41 =3D 116 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_dev =20 $42 =3D 0 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_ino $43 =3D 4 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_mode $44 =3D 8 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_nlink $45 =3D 10 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_uid =20 $46 =3D 12 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_gid $47 =3D 16 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_rdev $48 =3D 20 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_atim $49 =3D 24 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_mtim =20 $50 =3D 40 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_ctim $51 =3D 56 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_size =20 $52 =3D 72 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_blocks $53 =3D 80 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_blksize $54 =3D 88 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_flags =20 $55 =3D 92 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_gen =20 $56 =3D 96 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_birthtim $57 =3D 100 So after st_mode the offsets are wrong relative to struct nstat (native to armv7). /usr/include/sys/stat.h has: struct nstat { __uint32_t st_dev; /* inode's device */ __uint32_t st_ino; /* inode's number */ __uint32_t st_mode; /* inode protection mode */ __uint32_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of the file's owner = */ gid_t st_gid; /* group ID of the file's group = */ __uint32_t st_rdev; /* device type */ struct timespec st_atim; /* time of last access */ struct timespec st_mtim; /* time of last data = modification */ struct timespec st_ctim; /* time of last file status = change */ off_t st_size; /* file size, in bytes */ blkcnt_t st_blocks; /* blocks allocated for file */ blksize_t st_blksize; /* optimal blocksize for I/O */ fflags_t st_flags; /* user defined flags for file = */ __uint32_t st_gen; /* file generation number */ struct timespec st_birthtim; /* time of file creation */ /* * See comment in the definition of struct freebsd11_stat * above about the following padding. */ unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); }; = /wrkdirs/usr/ports/emulators/qemu-user-static/work/qemu-bsd-user-4ef7d07/b= sd-user/syscall_defs.h has: struct target_freebsd11_nstat { uint32_t st_dev; /* inode's device */ uint32_t st_ino; /* inode's number */ int16_t st_mode; /* inode protection mode */ int16_t st_nlink; /* number of hard links */ uint32_t st_uid; /* user ID of the file's owner */ uint32_t st_gid; /* group ID of the file's group */ uint32_t st_rdev; /* device type */ struct target_freebsd_timespec st_atim; /* time last accessed */ struct target_freebsd_timespec st_mtim; /* time last data = modification */ struct target_freebsd_timespec st_ctim; /* time last file status = change */ int64_t st_size; /* file size, in bytes */ int64_t st_blocks; /* blocks allocated for file */ uint32_t st_blksize; /* optimal blocksize for I/O */ uint32_t st_flags; /* user defined flags for file */ __uint32_t st_gen; /* file generation number */ /* __int32_t st_lspare; */ struct target_freebsd_timespec st_birthtim; /* time of file creation = */ /* * Explicitly pad st_birthtim to 16 bytes so that the size of * struct stat is backwards compatible. We use bitfields instead * of an array of chars so that this doesn't require a C99 compiler * to compile if the size of the padding is 0. We use 2 bitfields * to cover up to 64 bits on 32-bit machines. We assume that * CHAR_BIT is 8... */ unsigned int:(8 / 2) * (16 - (int)sizeof(struct = target_freebsd_timespec)); unsigned int:(8 / 2) * (16 - (int)sizeof(struct = target_freebsd_timespec)); } __packed; There are multiple issues here, for example: __uint32_t (native nstat) = vs. int16_t (target_nstat) for st_mode. Similarly for st_nlink. And there is = __packed changing the padding for another example. =3D=3D=3D Mark Millard marklmi at yahoo.com ( dsl-only.net went away in early 2018-Mar)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?62F581E3-EBB6-4980-BD20-4E121D64BBC5>