IRC channel logs

2026-06-28.log

back to list of logs

<diegonc>youpi, both files are the exactly the same ( https://paste.debian.net/hidden/9cb45759 ). I'm not sure there are other files worth comparing
<diegonc>*are exactly
<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>that is incorrect layout
<damo22>it should be time_value64_t = struct [2] of (MACH_MSG_TYPE_INTEGER_64 ....
<damo22>where do you see that
<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>that one is for mig64
<diegonc> https://cgit.git.savannah.gnu.org/cgit/hurd/mig.git/tree/type.c#n733
<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>thats interesting
<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> | ^~~~~~~~~~~~~~
<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> https://cgit.git.savannah.gnu.org/cgit/hurd/mig.git/tree/parser.y#n473
<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?
<damo22>but its passed in as bits?
<damo22>t->itAlignment is passed in
<damo22>no im wrong
<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 ..
<diegonc>yup
<damo22>because the complex_alignof is 4 bytes
<damo22>something is not detecting the int64_t
<damo22>i dont think its itLongDecl
<diegonc> https://cgit.git.savannah.gnu.org/cgit/hurd/mig.git/tree/type.c#n988
<diegonc>it's initialized there
<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
<diegonc>why not?
<damo22>$ cat test.defs
<damo22>subsystem test 10;
<damo22>type int64_t = MACH_MSG_TYPE_INTEGER_64;
<damo22>type time_value64_t = struct {
<damo22> int64_t seconds;
<damo22> int64_t nanoseconds;
<damo22>};
<damo22>$ ./gnu32/bin/i686-gnu-mig -v -n -cc cat - /dev/null < test.defs
<damo22>Subsystem test: base = 10
<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>is that not a bug?
<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>as in no alignment
<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>its a timer calibration bug
<damo22>with --enable-apic
<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>what it is now*
<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>i think that breaks user32
<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> exit(EXIT_FAILURE);
<damo22> }
<damo22> it->itName = ctype;
<damo22>- it->itAlignment = size;
<damo22>ie, the alignment should be set to the size of the integer just parsed
<solid_black>afternoon
<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>hmm that does not fix it
<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>aha gdb> run -v < test.defs
<damo22>Thread 4 hit Breakpoint 1, itStructDecl (min_type_size_in_bytes=16, required_alignment_in_bytes=4) at ../type.c:727
<damo22>i was right
<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}
<damo22>itAlignment of a int64_t is 4
<solid_black>that does sounds wrong
<damo22>that is not good
<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
<damo22>then the typechecking fails
<solid_black>for old-style structures, that would make sense
<solid_black>or maybe even not for them
<solid_black>but MACH_MSG_TYPE_INTEGER_64 is not a structure
<solid_black>it's a distinct type
<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>yes
<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
<damo22>ACTION ->bedtime
<diegonc>(ok, let's see if this works :P )
<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
<sneek>Okay.
<sneek>Okay.
<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?