I am not able to understand how bytes in memory are being mapped into a struct.
My machine is a little-endian x86_64. The code was compiled with gcc 4.7.0 from the Win64 mingw32-64 distribution for Win64.
These are contents of the relevant memory fragment:
…450002cf9fe5000040115a9fc0a8fe…
And this is the struct definition:
typedef struct ip4 {
unsigned int ihl :4;
unsigned int version :4;
uint8_t tos;
uint16_t tot_len;
uint16_t id;
uint16_t frag_off; // flags=3 bits, offset=13 bits
uint8_t ttl;
uint8_t protocol;
uint16_t check;
uint32_t saddr;
uint32_t daddr;
/*The options start here. */
} ip4_t;
When a pointer to such an structure (let it be *ip4
) is initialized to the starting address of the above pasted memory region, this is what the debugger shows for the struct’s fields:
ip4: address=0x8da36ce
ip4->ihl: address=0x8da36ce, value=0x5
ip4->version: address=0x8da36ce, value=0x4
ip4->tos: address=0x8da36d2, value=0x9f
ip4->tot_len: address=0x8da36d4, value=0x0
...
I see how ihl
and version are mapped: 4 bytes for a long integer, little-endian. But I don’t understand how tos
and tot_len
are mapped; which bytes in memory correspond to each one of them.
Thank you in advance.
3
tos
is mapped to 0x8da36d2, just 4 bytes after ihl
, and it uses the byte at that address for storing the value 9f
. The compiler seems to use 16-bit alignment here, so the start of tot_len
is two bytes later from 0x8da36d4
to 0x8da36d5
, and the value at 0x8da36d3
(which seems to be e5
in your example) is just unused garbage.
6