p1 is the actual distribution. p2 is the returned pointer, which refers to the memory behind the allocation point and leaves enough space for both binding and storing the actual allocated pointer in the first place. when aligned_free () is called, p1 will be fetched to execute "real" free ().
As for bit math, this gets a little more cumbersome, but it works.
p2=(void**)(((size_t)(p1)+offset)&~(alignment-1));
Remember that p1 is a reference to the actual location. For kicks, let's assume the following: 32-bit pointers:
alignment = 64 bytes, 0x40 offset = 0x40-1+4 = 0x43 p1 = 0x20000110, a value returned from the stock malloc()
The important thing is that the original malloc() allocates an extra 0x43 bytes of space above and above the original request. This is necessary to take into account both the mathematics of alignment and the space for a 32-bit pointer:
p2=(void**)(((size_t)(p1)+offset)&~(alignment-1));
p2 is aligned at the 0x40 boundary (that is, all bits in 0x3F are 0), and there is enough space left to store a 4-byte pointer for the original selection referenced by p1.
This was forever since I did the math alignment, so if I modified the bit, please someone would fix it.
source share