[Removing __packed did make the size and offsets match armv7 and the build worked based on the reconstructed qemu-arm-static.] On 2018-Dec-30, at 16:38, Mark Millard <marklmi_at_yahoo.com> wrote: > On 2018-Dec-28, at 12:12, Mark Millard <marklmi at yahoo.com> wrote: > >> On 2018-Dec-28, at 05:13, Michal Meloun <melounmichal at gmail.com> wrote: >> >>> Mark, >>> this is known problem with qemu-user-static. >>> Emulation of every single interruptible syscall is broken by design (it >>> have signal related races). Theses races cannot be solved without major >>> rewrite of syscall emulation code. >>> Unfortunately, nobody actively works on this, I think. >>> >> >> Thanks for the note setting some expectations. >> . . . > > > It turns out that I've been through (part of?) this before and > mikael.urankar_at_gmail.com had back then provided a qemu-user-static > patch (that might have been arm specific or 32-bit target specific > when running on a 64-bit host). (The qemu-user-static code structure > seems to have changed some afterwards and the patch is no longer > where he had pointed me to back then.) > > To show size and offsets on armv7 vs. armd64 for struct kevent > I use: > > # more kevent_size_offsets.c > #include "/usr/include/sys/event.h" // kevent > #include <stddef.h> // offsetof > #include <stdio.h> // printf > > int > main() > { > printf("%lu\n", (unsigned long) sizeof(struct kevent)); > printf("ident %lu\n", (unsigned long) offsetof(struct kevent, ident)); > printf("filter %lu\n", (unsigned long) offsetof(struct kevent, filter)); > printf("flags %lu\n", (unsigned long) offsetof(struct kevent, flags)); > printf("fflags %lu\n", (unsigned long) offsetof(struct kevent, fflags)); > printf("data %lu\n", (unsigned long) offsetof(struct kevent, data)); > printf("udata %lu\n", (unsigned long) offsetof(struct kevent, udata)); > printf("ext %lu\n", (unsigned long) offsetof(struct kevent, ext)); > return 0; > } > > It ends up showing on armv7 (under qemu-arm-static insteead of native, not > that it matters here): > > # ./a.out > 64 > ident 0 > filter 4 > flags 6 > fflags 8 > data 16 > udata 24 > ext 32 > > On amd64 (native) it ends up as: > > # ./a.out > 64 > ident 0 > filter 8 > flags 10 > fflags 12 > data 16 > udata 24 > ext 32 > > Thus a translation of layout is required when hosted. This is for: > > struct kevent { > __uintptr_t ident; /* identifier for this event */ > short filter; /* filter for event */ > unsigned short flags; /* action flags for kqueue */ > unsigned int fflags; /* filter flag value */ > __int64_t data; /* filter data value */ > void *udata; /* opaque user data identifier */ > __uint64_t ext[4]; /* extensions */ > }; > > But qemu-user-static has for translation purposes: > > struct target_freebsd_kevent { > abi_ulong ident; > int16_t filter; > uint16_t flags; > uint32_t fflags; > int64_t data; > abi_ulong udata; > uint64_t ext[4]; > } __packed; > > (note the __packed) for which in amd64's qemu_arm_static has > the size and offsets: > > # gdb qemu-arm-static > . . . > (gdb) p/d sizeof(struct target_freebsd_kevent) > $1 = 56 > (gdb) p/d &((struct target_freebsd_kevent *)0)->ident > $2 = 0 > (gdb) p/d &((struct target_freebsd_kevent *)0)->filter > $3 = 4 > (gdb) p/d &((struct target_freebsd_kevent *)0)->flags > $4 = 6 > (gdb) p/d &((struct target_freebsd_kevent *)0)->fflags > $5 = 8 > (gdb) p/d &((struct target_freebsd_kevent *)0)->data > $6 = 12 > (gdb) p/d &((struct target_freebsd_kevent *)0)->udata > $7 = 20 > (gdb) p/d &((struct target_freebsd_kevent *)0)->ext > $8 = 24 > > which which does not match the armv7 offsets for > data, udata, or ext and does not have the right size > for struct target_freebsd_kevent[] indexing to > match armv7's struct target_freebsd_kevent[] indexing. > > This in turn makes the do_freebsd_kevent code do the wrong > thing in its: > > struct target_freebsd_kevent *target_changelist, *target_eventlist; > . . . > for (i = 0; i < arg3; i++) { > __get_user(changelist[i].ident, &target_changelist[i].ident); > __get_user(changelist[i].filter, &target_changelist[i].filter); > __get_user(changelist[i].flags, &target_changelist[i].flags); > __get_user(changelist[i].fflags, &target_changelist[i].fflags); > __get_user(changelist[i].data, &target_changelist[i].data); > /* __get_user(changelist[i].udata, &target_changelist[i].udata); */ > #if TARGET_ABI_BITS == 32 > changelist[i].udata = (void *)(uintptr_t)target_changelist[i].udata; > tswap32s((uint32_t *)&changelist[i].udata); > #else > changelist[i].udata = (void *)(uintptr_t)target_changelist[i].udata; > tswap64s((uint64_t *)&changelist[i].udata); > #endif > __get_user(changelist[i].ext[0], &target_changelist[i].ext[0]); > __get_user(changelist[i].ext[1], &target_changelist[i].ext[1]); > __get_user(changelist[i].ext[2], &target_changelist[i].ext[2]); > __get_user(changelist[i].ext[3], &target_changelist[i].ext[3]); > } > . . . > for (i = 0; i < arg5; i++) { > __put_user(eventlist[i].ident, &target_eventlist[i].ident); > __put_user(eventlist[i].filter, &target_eventlist[i].filter); > __put_user(eventlist[i].flags, &target_eventlist[i].flags); > __put_user(eventlist[i].fflags, &target_eventlist[i].fflags); > __put_user(eventlist[i].data, &target_eventlist[i].data); > /* __put_user(eventlist[i].udata, &target_eventlist[i].udata);*/ > #if TARGET_ABI_BITS == 32 > tswap32s((uint32_t *)&eventlist[i].data); > target_eventlist[i].data = (uintptr_t)eventlist[i].data; > #else > tswap64s((uint64_t *)&eventlist[i].data); > target_eventlist[i].data = (uintptr_t)eventlist[i].data; > #endif > __put_user(eventlist[i].ext[0], &target_eventlist[i].ext[0]); > __put_user(eventlist[i].ext[1], &target_eventlist[i].ext[1]); > __put_user(eventlist[i].ext[2], &target_eventlist[i].ext[2]); > __put_user(eventlist[i].ext[3], &target_eventlist[i].ext[3]); > } > > > > I'll eventually do something to have struct target_freebsd_kevent for > amd64-native targeting armv7 and see if that is sufficient to avoid the > problem in my context. Previously removing the __packed was enough to > make the structure the same size with the same offsets as for armv7. > (Such might not have been appropriate to all targets.) > > armv6 would have the same problem as I understand things. Using commented out __packed in: struct target_freebsd11_kevent { abi_ulong ident; int16_t filter; uint16_t flags; uint32_t fflags; abi_long data; abi_ulong udata; } ; // __packed; struct target_freebsd_kevent { abi_ulong ident; int16_t filter; uint16_t flags; uint32_t fflags; int64_t data; abi_ulong udata; uint64_t ext[4]; } ; // __packed; in /wrkdirs/usr/ports/emulators/qemu-user-static/work/qemu-bsd-user-4ef7d07/bsd-user/syscall_defs.h was sufficient to allow the multimedia/gstreamer1-qt_at_qt5 build to complete: no more hang-up. So this is likely what is wrong for the packages-builders as well. === Mark Millard marklmi at yahoo.com ( dsl-only.net went away in early 2018-Mar)Received on Mon Dec 31 2018 - 00:26:16 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:19 UTC