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) = %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) = 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 = 56
(gdb) p/d &((struct target_msghdr *)0)->msg_name 
$2 = 0
(gdb) p/d &((struct target_msghdr *)0)->msg_namelen
$3 = 8
(gdb) p/d &((struct target_msghdr *)0)->msg_iov    
$4 = 16
(gdb) p/d &((struct target_msghdr *)0)->msg_iovlen
$5 = 24
(gdb) p/d &((struct target_msghdr *)0)->msg_control
$6 = 32
(gdb) p/d &((struct target_msghdr *)0)->msg_controllen
$7 = 40
(gdb) p/d &((struct target_msghdr *)0)->msg_flags    
$8 = 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) = 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.


===
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>