IRC channel logs
2026-06-28.log
back to list of logs
<youpi>so then it's the kernel that misses a piece of conversion <damo22>i think it might be the msg_usize function <damo22>which is only defined in __LP64__ && USER32 case <diegonc>I've stepped through it. it returns 52 which is the correct user size from what I recall <diegonc>there are also a few more function for USER32 in ipc/copy_user.c <diegonc>mig seems to output sizes in multiples of the word size: <diegonc>Type time_value64_t = struct [4] of (MACH_MSG_TYPE_INTEGER_32, 32) <diegonc>but I cannot see where the 64bit definition gets translated to the user32 layout <damo22>it should be time_value64_t = struct [2] of (MACH_MSG_TYPE_INTEGER_64 .... <diegonc>I added the -v flag to the USER_MIG command in user-qemu.mk <diegonc>Type time_value64_t = struct [2] of (MACH_MSG_TYPE_INTEGER_64, 64) <diegonc>there is where mig decides the size of each struct member <diegonc>it takes into account some kind of required alignment. but I couldn't trace where it cames from <damo22>maybe we need to align the struct to 64 <damo22>ok i added __aligned(8) and now i get a failed static assert <damo22>Type time_value64_t = struct [4] of (MACH_MSG_TYPE_INTEGER_32, 32) <damo22>x86_64-gnu-gcc -m32 -L/usr/lib/gcc-cross/i686-linux-gnu/15 -ftrivial-auto-var-init=pattern -static -nostartfiles -nolibc -ffreet <damo22>./tests/mig-out/mach_host.user.c: In function ‘host_set_time64’: <damo22>./tests/mig-out/mach_host.user.c:4330:9: error: static assertion failed: "Request expected to be 44 bytes" <damo22> 4330 | _Static_assert(sizeof(Request) == 44, "Request expected to be 44 bytes"); <damo22>the type is still being set wrong <diegonc>the alignment is something the mig parser computes from the types definitions. here is how it's used by the struct rule <diegonc>I still can't find where t->itAlignment is set <diegonc>anyway, from what y oupi said earlier it seems the kernel is missing some translation back to user32 layout <damo22>no, i think the alignment is out <damo22>causing mig to set Type time_value64_t = struct [4] of (MACH_MSG_TYPE_INTEGER_32, 32) <diegonc>found it: (mig) type.c:553: it->itAlignment = MIN(complex_alignof, size / 8); <diegonc>complex_alignof is somesthing sizeof(uintptr_t) <diegonc>which for mig32 is 4 bytes (less than 64/8) <damo22>that means 64 bit types will never be set by mig in 32 bit <damo22>isnt it that itStructDecl expects second param in bytes? <diegonc>> damo22: that means 64 bit types will never be set by mig in 32 bit <diegonc>not really. I made a little test earlier and a int64_t, outside a struct (!), is encoded as a 64 bit integer <damo22>yes but 64 bit types embedded in structs will always be 2x32x .. <damo22>because the complex_alignof is 4 bytes <damo22>something is not detecting the int64_t <damo22>the problem is ipc_type_t *t = itPrevDecl($1); and then it uses t->itAlignment to set the struct alignment <damo22>somehow the previous decl isnt int64 <damo22>type int64_t = MACH_MSG_TYPE_INTEGER_64; <damo22>$ ./gnu32/bin/i686-gnu-mig -v -n -cc cat - /dev/null < test.defs <damo22>Type int64_t = (MACH_MSG_TYPE_INTEGER_64, 64) <damo22>Type time_value64_t = struct [4] of (MACH_MSG_TYPE_INTEGER_32, 32) <damo22>youpi: what is the smallest alignment that a mig type should have? <damo22>if its a one byte char, can it be aligned to 1 byte? <damo22>i wrote this and it fixes the bug in user32: <damo22> /* complex_alignof might be smaller than int64_t */ <damo22> it->itAlignment = MIN(sizeof(int64_t), size / 8); <damo22>now i have only 2 CI failures, on --enable-user32 --enable-ncpus=8 <damo22>x86_64 (--enable-kdb, --disable-apic --enable-ncpus=1, --enable-user32) Success <damo22>x86_64 (--enable-kdb, --enable-apic --enable-ncpus=1, --enable-user32) Success <youpi>damo22, diegonc: note that we *cannot* change the 32b user typing <youpi>userland expects what it is not <youpi>I guess the alignment could be as little as the type of the int itself, but that's only from C rationale, I don't know the details of mig enough to be really sure <damo22>youpi: your commit changed the alignment for 64 bit integers in 2025, but i think it was missing the minimum itAlignment for 64 bit ints <damo22>Author: Samuel Thibault <samuel.thibault@ens-lyon.org> <damo22>Date: Mon Jun 9 23:30:36 2025 +0200 <damo22> Fix aligning 64b types in structures <damo22>so the minimum alignment in mig32 is 4 bytes even for 64 bit types <damo22>because the size of the reply is only computed in the user32 case, otherwise it is returned same as kernel (?) <damo22>this line should not have been removed in 2023: <damo22>@@ -806,7 +800,6 @@ itCIntTypeDecl(const_string_t ctype, const size_t size) <damo22>ie, the alignment should be set to the size of the integer just parsed <solid_black>at this point, I'd ping Flavio, if he's still around <damo22>but only for simple integer types does it need to do that, so the line that was deleted could be reinstated i think <damo22>as far as i can see, the problem is in mig, in itStructDecl(u_int min_type_size_in_bytes, u_int required_alignment_in_bytes) the required_alignment_in_bytes is somehow passed in as 4, for a struct containing two int64_t members <solid_black>but it doesn't only get the alignment wrong, it gets the whole type wrong? <damo22>if the alignment is passed in wrong it recomputes the type in that function per struct member <damo22>how do i run migcom in gdb and pass it a file on stdin? <damo22>Thread 4 hit Breakpoint 1, itStructDecl (min_type_size_in_bytes=16, required_alignment_in_bytes=4) at ../type.c:727 <damo22>$2 = {itName = 0x200000007820 "int64_t", itNext = 0x200000007780, itTypeSize = 8, itPadSize = 0, itMinTypeSize = 8, itAlignment = 4, itInName = 11, itOutName = 11, itSize = 64, itNumber = 1, itInLine = true, itLongForm = false, itDeallocate = d_NO, itInNameStr = 0x100011df8 "MACH_MSG_TYPE_INTEGER_64", itOutNameStr = 0x100011df8 "MACH_MSG_TYPE_INTEGER_64", itFlags = 0, itStruct = true, itString = false, itVarArray = false, itIndefinite = f <damo22>alse, itUserlandPort = false, itKernelPort = false, itElement = 0x0, itUserType = 0x200000007820 "int64_t", itServerType = 0x200000007820 "int64_t", itTransType = 0x200000007820 "int64_t", itInTrans = 0x0, itInTransPayload = 0x0, itOutTrans = 0x0, itDestructor = 0x0} <youpi>no, it is right, on a 32b land <youpi>alignof(uint64_t) does return 4 on 32b <damo22>// If the struct is short or int aligned, use that as the base type. <damo22>so itStructDecl recomputes the struct member types based on the input required_alignment_int_bytes param <damo22>if the param is 4, it says the the base element type is 32 bit word and the number of elems is final struct bytes / 4 <damo22>how does that work if the member is 64 bits wide? <damo22>i mean, it will add up in bytes but it wont reflect the actual size of the members <solid_black>...hm, I think I might understand what you're saying <solid_black>does it behave differently if instead time_value64_t is defined as struct[2] of int64_t? <solid_black>in other words, is that an artifact of how new-style structs are implemented? <damo22>the alignof(int64_t) = 4 is now making the struct[2] of int64_t appear as struct[4] of int32_t, because its an artifact of how the new style structs are implemented <damo22>and that breaks on user32 because the size of the reply is computed instead of copied from the message <diegonc>sneek later tell solid_black: I can't setup 9pfs successfully. On the GNU/Hurd side I get: <diegonc>sneek later tell solid_black: (term 1) demo@debian:~/dev$ 9pfs/9pfs -D -S host-hurd/ 172.19.75.100/hurd <diegonc>sneek later tell solid_black: (term 2) demo@debian:~/dev$ ls host-hurd <diegonc>sneek later tell solid_black: (term 2) ls: cannot access 'host-hurd': Operation not permitted <diegonc>sneek later tell solid_black: and in the host side: <diegonc>sneek later tell solid_black: demo@charsi:~/hurd$ sudo diod -e /home/demo/hurd -n -f <diegonc>sneek later tell solid_black: diod: attach(1000@172.19.75.100:/hurd): access denied for export: Operation not permitted <diegonc>sneek later tell solid_black: any idea?