[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) = %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) = 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 = 116 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_dev $42 = 0 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_ino $43 = 4 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_mode $44 = 8 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_nlink $45 = 10 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_uid $46 = 12 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_gid $47 = 16 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_rdev $48 = 20 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_atim $49 = 24 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_mtim $50 = 40 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_ctim $51 = 56 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_size $52 = 72 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_blocks $53 = 80 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_blksize $54 = 88 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_flags $55 = 92 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_gen $56 = 96 (gdb) p/d &((struct target_freebsd11_nstat *)0)->st_birthtim $57 = 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/bsd-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. === Mark Millard marklmi at yahoo.com ( dsl-only.net went away in early 2018-Mar) _______________________________________________ freebsd-ports@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-ports To unsubscribe, send any mail to "freebsd-ports-unsubscr...@freebsd.org"