Re: MiG: New-style structs not working as expected on 32 bit userspace
Sergey Bugaev <[email protected]> Mon, 29 Jun 2026 11:42:08 +0300
| Newsgroups | gmane.os.hurd.bugs |
|---|---|
| Message-ID | <CAN9u=Hf+iC1dNGXyTOYnDHjc5O05_YPHwJUseWKRVuQE5sYThA@mail.gmail.com> |
On Mon, Jun 29, 2026 at 9:47 AM Damien Zammit <[email protected]> wrote: > It seems complex_alignof = 4 is causing the structures to recompute > their member sizes. Now while the total number of bytes still matches, > on (__LP64__ && USER32) kernel with 32 bit userspace, mig_usize is > computed differently in the user32 case, thus we get a MIG_TYPE_ERROR on > some RPCs that use 64 bit types embedded in structs. To add some more context from my side (as discussed on IRC): In versions of Mach that use "typed IPC" (such as in our case GNU Mach), an IPC message body logically consists of elements (items, fields — I don't remember if there's an established term for this) that have types like MACH_MSG_TYPE_INTEGER_32 (a 32-bit integer) and MACH_MSG_TYPE_COPY_SEND (Mach port right with copy-send semantics) and arrays of those (plus out-of-line types). On each particular CPU architecture / ABI, such a sequence of elements has an in-memory layout, with endianness, alignment/padding, and such. But logically those are not a part of the message, that's just how a message is represented in-memory for a particular ABI. Consider also that Mach IPC was supposed to be network-transparent (see netname / netmsg and NORMA). The two peers might be running with different ABIs, perhaps one is big-endian 32-bit PPC and the other is little-endian 64-bit AArch64, or something like that. The way a message would be laid out in memory would be quite different between these two peers, but the logical contents of a message (e.g. a 32-bit integer with the value of 1234, followed by a C string saying "test", followed by an array of 4 booleans with the values {true, false, false, true}) would be identical. The way the message would be represented over the network is probably some yet different ABI/format, what's important is that it preserves this logical structure of the message. Even without actual network transparency, there's an issue of doing local messaging between tasks/peers using a different ABI. Apple had PPC and x86 processes coexisting, and now x86_64 and AArch64 ones (though they use untyped MIG); we decided against supporting multiple userland ABIs on the same kernel, but we still have the different ABIs between the kernel and the userland when running in user32 mode. I'm saying all this to emphasize that 'struct [4] of (MACH_MSG_TYPE_INTEGER_32, 32)' and 'struct [2] of (MACH_MSG_TYPE_INTEGER_64, 64)' are not the same thing at all, even though they have a similar/identical in-memory layout on some ABIs. There is no 'struct' at Mach IPC level, that's a MIG concept, but one produces an array of 4 MACH_MSG_TYPE_INTEGER_32's, and the other an array of 2 MACH_MSG_TYPE_INTEGER_64's, and those are different types. So with the new-style structs, MIG takes the same type definition, such as type new_style_struct_t = struct { int64_t field; }; and maps it to different Mach IPC level field types, depending on the local ABI. That's not great. Sergey