Next: Pinned Structs, Previous: Field Initializers, Up: Structs [Contents][Index]
In structs, each field is associated with an offset, which is relative to the beginning of the struct. This is the offset used when reading and writing the field from/to the IO space when mapping.
The offset is reset to zero bits at the beginning of the struct type, and it is increased by the size of the fields:
struct
{
/* Offset: 0#b */
uint<1> f1; /* Offset: 1#b */
sint<7> f2; /* Offset: 1#B */
int f3; /* Offset: 5#B */
Bar f4; /* Offset: 23#B */
}
It is possible to specify an alternative offset for a field using a field label.
Consider for example an entry in an ELF symbol table. Each entry has
a st_info field which is 64-bits long, that in turn can be
interpreted as two fields st_bind and st_type.
The obvious solution is to encode st_info as a sub-struct, like
this:
struct
{
elf32_word st_name;
struct
{
uint<60> st_bind;
uint<4> st_type;
} st_info;
}
However, that makes it inconvenient to access the value of
st_info as an integral value, using the bit-concatenation
operator symbol.st_info.st_bind::symbol.st_info.st_type. We
can use labels instead:
struct
{
elf32_word st_name;
elf64_word st_info;
uint<60> st_bind @ 4#B;
uint<4> st_type @ 4#B + 60#b;
}
The resulting struct has fields st_info, st_bind and
st_type, with the last two overlapping the first.