As we all know, the current language provided by MIG has several drawbacks:
- Requires all types to be described twice: first in the C header file and then in the defs file. This is problematic since types need to have the same size in both files and also the same name.
- It does not allow arbitrary types since every datum sent through mach_msg needs to be decomposed into smaller types (MACH_MSG_TYPE_INTEGER_32 and friends).
- Structs are fairly limited since they are essentially arrays and require careful modification when the C definitions are changed. This is bad for making the Hurd run on x86_64 since the size of structs may change depending on the size of its data members.
I'm proposing a redesign of MIG that will allow us to get over these issues. The main idea is to bring the MIG language closer to C, by allowing MIG to read a subset of the C language including typedefs, structs, arrays, unions and basic C types. This has several advantages:
- Type definitions will no longer need to be defined twice. C headers are #included and MIG will understand them. We won't need to worry about C not understanding the new types.
- MIG will map standard C types into MACH_MSG_TYPE_* values automatically. The user will never need to understand these basic mach message types in order to write RPC routines. This mapping will be done in such a way that will make porting stubs to 64bits effortless.
Over last weekend, I have worked on a fork of MIG that is able to parse most of the C language used in Mach and Hurd headers, including structs, typedefs, arrays and unions. The link for the repository is https://github.com/flavioc/mig
Here's a few examples of MIG files using the new syntax:https://raw.githubusercontent.com/flavioc/mig/c-types/tests/good/array.defshttps://raw.githubusercontent.com/flavioc/mig/c-types/tests/good/struct.defs
A few notes about the implementation. For structs, I carefully check if it's possible to compose the members of the structure using their mach types. If all members are 32bit integers, then the itSize and itNumber of the ipc_type_t of the struct are set to use MACH_MSG_TYPE_INTEGER_32. This allows MIG to build stubs that can be useful for debugging with rpctrace and so forth. However, if the members are not using the same mach type, then I simply use MACH_MSG_TYPE_BYTE. Still, note that the function that creates struct types (structCreateNew) still requires some work to take padding into account.
However, there's still some work to do in terms of defining the semantics of C types. I propose the following basic rules for routine arguments:
struct x: passed as a value to the RPC function and transmitted in-line.
struct x*: passed as a pointer to the RPC function and transmitted in-line.
int x: passed as a pointer along with a count and is transmitted inline or out of line depending on the size.
int x[N]: passed as a pointer and transmitted in-line.