Automatic Translation of Header Files From C++

Describes how C++ header files are translated into the assembler language that the bootstrap requires.

Some header files that the bootstrap uses are shared with the Kernel and are written in C++. The header files are shared to avoid duplicate definitions of, for example, super page layout in the kernel and in the bootstrap. Since the bootstrap is written in assembler, the C++ header files must be translated to assembler-syntax include files.

This is done automatically under the control of the generic makefile. The translation tool can produce include files in ARMASM, GNU AS or Turbo Assembler (for X86) syntax; the examples will all be in ARMASM syntax.

It should be noted that the translation tool does not process #include directives or any other preprocessor directives. Only the types listed below and types created from those (by typedef or class/struct declaration) will be recognised.

The following elements of C++ header files are translated:

Compile time constants, both at file and class scope

Constants at file scope have the same name in the assembler include file and constants at class scope have the name <class name>_<constant name> in the assembler include file. Initialiser values may be expressions and may involve previously-defined constants or enumerators as well as sizeof operations applied to previously-defined types.

For example:

const TInt KBufferSize = 1024;
class X { const TInt KClassConstant = 100; };

translates to:

KBufferSize            EQU 0x00000400
X_KClassConstant     EQU 0x00000064

Enumerators, both at file and class scope

For example:

enum T1 {E1=0, E2=8, E3};
class X { enum {EE1=-1, EE2, EE3}; };

translates to:

E1                    EQU    0x00000000
E2                    EQU    0x00000008
E3                    EQU    0x00000009
X_EE1                EQU    0xFFFFFFFF
X_EE2                EQU    0x00000000
X_EE3                EQU    0x00000001

Offset of a class member within the class

For example:

class X { TInt iX; TInt iY; TInt iZ[16]; };

translates to:

X_iX                EQU    0x00000000
X_iY                EQU    0x00000004
X_iZ                EQU    0x00000008
X_iZ_spc            EQU    0x00000004
X_sz                EQU    0x00000048

The offset of a class member within the class is given the assembler name <class>_<member>. For an array member, this offset is the offset of the first element of the array within the class and <class>_<member>_spc is the size of each array element. The overall size of the class is given the assembler name <class>_sz.

When computing these offsets and sizes the following basic types are known to the translation tool:

TInt8, TUint8 = 1 byte
TInt16, TUint16 = 2 bytes aligned to 2 byte boundary
TInt32, TUint32, TInt, TUint, enum, TLinAddr, TPte, TPde = 4 bytes aligned to 4 byte boundary
TInt64, TUint64 = 8 bytes aligned to 8 byte boundary

The tool will produce an error if an attempt is made to use a TInt64 or TUint64 which is not aligned on an 8 byte boundary. This is done to avoid incompatibilities between GCC and EABI compilers since the tool is not aware which is being used to compile the kernel.