Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 4 Jan 2019 19:06:32 -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>
Subject:   qemu-x86_64-static has target_msghdr's msg_controllen field with the wrong size so its msg_flags is at the wrong offset and target_msghdr is too large
Message-ID:  <1A600189-EBEB-49A3-AAF0-C188D39286FE@yahoo.com>

next in thread | raw e-mail | index | archive | help
[qemu-aarch64-static has the same problem but qemu-armv7-sstatic does =
not. The context here
is FreeBSD head -r341836 based and ports head -r488859 based.]

Note: I assume that "struct target_msghdr" is meant to match the memory =
layout
of the target's native "struct msghdr". Otherwise the reported =
differences
below could be irrelevant.

For amd64 and aarch64 the following code:

        printf("sizeof(struct msghdr) =3D %lu\n", (unsigned long) =
sizeof(struct msghdr));
        printf("msg_name %lu\n", (unsigned long) offsetof(struct msghdr, =
msg_name));
        printf("msg_namelen %lu\n", (unsigned long) offsetof(struct =
msghdr, msg_namelen));
        printf("msg_iov %lu\n", (unsigned long) offsetof(struct msghdr, =
msg_iov));
        printf("msg_iovlen %lu\n", (unsigned long) offsetof(struct =
msghdr, msg_iovlen));
        printf("msg_control %lu\n", (unsigned long) offsetof(struct =
msghdr, msg_control));
        printf("msg_controllen %lu\n", (unsigned long) offsetof(struct =
msghdr, msg_controllen));
        printf("msg_flags %lu\n", (unsigned long) offsetof(struct =
msghdr, msg_flags));


produces:

sizeof(struct msghdr) =3D 48
msg_name 0
msg_namelen 8
msg_iov 16
msg_iovlen 24
msg_control 32
msg_controllen 40
msg_flags 44

Note: msg_controllen was apparently 4 bytes wide on these 64-bit =
architectures.


However gdb reports for qemu-x86_64-static and qemu-aarch64-static:

(gdb) p/d sizeof(struct target_msghdr)
$1 =3D 56
(gdb) p/d &((struct target_msghdr *)0)->msg_name=20
$2 =3D 0
(gdb) p/d &((struct target_msghdr *)0)->msg_namelen
$3 =3D 8
(gdb) p/d &((struct target_msghdr *)0)->msg_iov   =20
$4 =3D 16
(gdb) p/d &((struct target_msghdr *)0)->msg_iovlen
$5 =3D 24
(gdb) p/d &((struct target_msghdr *)0)->msg_control
$6 =3D 32
(gdb) p/d &((struct target_msghdr *)0)->msg_controllen
$7 =3D 40
(gdb) p/d &((struct target_msghdr *)0)->msg_flags   =20
$8 =3D 48

Note the larger size (56 instead of 48) and that msg_controllen 's size
puts msg_flags at the wrong offset.



Notably for armv7, gdb's information for armv7 agrees with:

sizeof(struct msghdr) =3D 28
msg_name 0
msg_namelen 4
msg_iov 8
msg_iovlen 12
msg_control 16
msg_controllen 20
msg_flags 24

Apparently msg_controllen should always be 4 bytes wide, even on
64-bit architectures instead of tracking the 64-bit vs. 32-bit
status for the architecture.


=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?1A600189-EBEB-49A3-AAF0-C188D39286FE>