I'm trying to steal two LSB bits from address and I have written the following inline functions. I want to confirm if this works on both 64 and 32 bit machines.
I used stealing bits from a pointer post as reference.
I get a weird bug where getAddress() returns 0x100
0x1
is fine as setFlag1(NULL)
will return this address
0x2
is fine as setFlag2(NULL)
will return this address
0x11
is also fine as setFlag1(NULL)
and setFlag2(NULL)
will return this address
But I'm not sure what combination will return 0x100
#define UINTPTR_MAX_XOR_WITH_1 (uintptr_t) (UINTPTR_MAX ^ 0x1)
#define UINTPTR_MAX_XOR_WITH_2 (uintptr_t) (UINTPTR_MAX ^ 0x2)
#define UINTPTR_MAX_XOR_WITH_3 (uintptr_t) (UINTPTR_MAX ^ 0x3)
struct node
{
unsigned long key;
struct node* lChild; //format <address,flag2,flag1>
struct node* rChild; //format <address,flag2,flag1>
};
static inline struct node* getAddress(struct node* p)
{
return (struct node*)((uintptr_t) p & UINTPTR_MAX_XOR_WITH_3);
}
static inline bool isFlag2(struct node* p)
{
return (uintptr_t) p & 0x2;
}
static inline bool isFlag1(struct node* p)
{
return (uintptr_t) p & 0x1;
}
static inline struct node* setFlag1(struct node* p)
{
return((struct node*) (((uintptr_t) p & UINTPTR_MAX_XOR_WITH_1) | 0x1));
}
static inline struct node* unsetFlag1(struct node* p)
{
return((struct node*) (((uintptr_t) p & UINTPTR_MAX_XOR_WITH_1)));
}
static inline struct node* setFlag2(struct node* p)
{
return((struct node*) (((uintptr_t) p & UINTPTR_MAX_XOR_WITH_2) | 0x2));
}