What is this type casting doing?
ph = (struct Proghdr *)((uint8_t *) ELFHDR ELFHDR->e_phoff);
Here, ELFHDR
is already defined as #define ELFHDR ((struct Elf *) 0x10000)
.
I want to ask: At the end, the value in ph
will be (struct Proghdr *)
then what is the need for the (uint8_t *)
?
I will be grateful if someone solves my problem related to type-casting.
CodePudding user response:
Pointer arithmetic in C is performed in units whose size is that of the pointed-to type. So, for example, if p
is a pointer to a double
, then p = p 1
will add the size (in bytes) of a double
to the address stored in p
.
In your case, the e_phoff
member of the pointed-to structure contains a byte offset for some particular data; however, simply adding that value to the ELFHDR
pointer itself (which is of Elf*
type) would add that value multiplied by the size of the Elf
structure. So, in order to properly use that byte offset, the pointer is first cast to a uint8_t*
, so that any pointer arithmetic is performed in terms of raw (single) bytes.
CodePudding user response:
Remember the equivalence p[i] == *( p i )
.
Given pointer p
and integer i
, p i
advances pointer p
by i
times the size of *p
.
For example, you see p
advanced by 8 times the time size of a uint32_t
in the following:
uint32_t a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
uint32_t *p = a;
p = p 8;
printf( "%" PRIu32 "\n", *p ); // 8
So if you wanted to advance the pointer by i
bytes, you'd need a pointer to a byte (char
).
uint32_t a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
uint32_t *p = a;
p = (uint32_t *)( (char *)p 8 );
printf( "%" PRIu32 "\n", *p ); // 2
uint8_t
is used as an equivalent of char
in the snippet you posted.
Demo on Compile Explorer