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

Mark Millard marklmi at yahoo.com
Sat Jan 5 03:06:37 UTC 2019


[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)



More information about the freebsd-ports mailing list