Reputation: 4315
I am not able to understand why is addr being typecasted to long, and then complemented with expression.. basically the whole line involving the calculation of peekAddr
void *addr;
char *peekAddr ;
peekAddr = (char *) ((long)addr & ~(sizeof(long) - 1 ) ) ;
peekWord = ptrace( PTRACE_PEEKDATA, pid, peekAddr, NULL ) ;
Upvotes: 2
Views: 1415
Reputation: 363817
It's cast to long
because (1) you can't do any operations on a void*
except cast it and (2) on the author's platform, a void*
value just so happens to fit in a long
. He should really have used uintptr_t
or size_t
instead.
What the piece of code does:
sizeof(long) - 1
is most likely either 3 or 7, depending on the platform.
~(sizeof(long) - 1)
is a bitmask that selects all but the last few bits.
((long)addr & ~(sizeof(long) - 1))
is addr
rounded down/aligned to address a long
-sized chunk. Rounding occurs because the last lg(3) or lg(7) bits are zeros while the rest is copied from addr
(where lg is integer binary logarithm).
Upvotes: 4
Reputation: 215547
This is a really ugly, unportable way of doing
peakAddr = (char *)addr - ((uintptr_t)addr & -(uintptr_t)sizeof(long));
Note that the original version not only relies on successful round trip conversion of pointers to long
and back, but also on size_t
(the type of the result of the sizeof
operator) being the same width or wider than long
. If it's not, the bitmask generated with ~
would zero-extend in the upper bits and obliterate part of the pointer.
Basically, you should make a mental note that whatever program you found this in is bad code and not look to it as a source of ideas...
Upvotes: 3
Reputation: 308520
This will have a bug on some compilers where sizeof(long) < sizeof(char*)
, such as Microsoft's.
sizeof(long)-1
is creating a bit mask corresponding to the size of a long
. This is a trick that only works on numbers that are a power of 2. The ~
in front inverts it, so now it's a mask of all the address bits that should remain unchanged when you're trying to align an address. The bitwise &
is clearing the bottom bits of the address to make it align.
Upvotes: 1
Reputation: 1827
sizeof (long) = (0)00000100
sizeof(long)-1 = (0)00000011
~(sizeof(long)-1) = (1)11111100
so 2 bits set to 0 make the address aligned to 4 bytes. additionally it's mostly used when the address was already incremented by sizeof(long)-1
Upvotes: 5
Reputation: 4869
you basically make peekAddr always aligned on sizeof(long) adresses. the line generates a bitmask and binary ands this to the peek address. The line strips the last sizeof(long)-1 bits from the peekAddr.
hth
Mario
Upvotes: 1