Hi

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.defs
https://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.

Also, for MIG types that use translation (intran, outtran) and payloads, we
can create a new construct such as "modtype <type> intran: ... outtran:
....;" which forces MIG to update the behavior of a type defined previously.

Another issue are types such as MACH_MSG_TYPE_COPY_SEND that allows us to
send port rights. For this, I think we should provide them by default by
using type names such as mach_port_copy_send_t and disallow any use of such
types in structs or typedefs.

Flavio

Reply via email to