I am trying to serialize PHP opcode. I am confused with code. Please check following code. What is the meaning of the code.
(ptr) = (void*)((char*)(ptr) - (char*)script->mem)
How to serialize op_array
?
I am trying to serialize PHP opcode. I am confused with code. Please check following code. What is the meaning of the code.
(ptr) = (void*)((char*)(ptr) - (char*)script->mem)
How to serialize op_array
?
So, this is an old game coders trick, intended to serialise/deserialise a pointer to/from disk.
It's a little dirty, but lets see if I can explain somehow. Using a vastly oversimplified example, lets imagine I have this struct:
struct FileContents
{
char text[10] = {0,1,2,3,4,5,6,7,8,9};
char* ptr = text + 5; //< point to element 5
};
and I want to read/write that struct using fread/fwrite in one go. If i was to simply do:
void writeFile(FileContents contents)
{
FILE* fp = fopen("blah.dat", "wb");
fwrite(&contents, sizeof(FileContents), 1, fp);
fclose(fp);
}
This would work fine for the values stored in contents.text, but would horribly fail for contents.ptr (since this pointer is referring to a memory address, and it's unlikely we will be able to re-claim that same memory location if we wanted to read the data again).
As such, we need an unfix/refix operation on all the pointer values. We can achieve this by doing:
struct FileContents
{
char text[10] = {0,1,2,3,4,5,6,7,8,9};
void* ptr = (text + 5); //< point to element 5
// convert 'ptr' to be an integer offset from the start of the struct
void unfix()
{
// heres the first byte we will write to the file
char* startOfFile = (char*)this;
// here's the problematic pointer value.
char* ptrValue = ptr;
// now lets compute a byte offset from the start of the struct,
// to the memory location ptr is pointing to...
// (in this case, the offset will be 5)
size_t offset = ptrValue - startOfFile;
// now lets modify the value of ptr so that it now stores a byte
// offset, rather than a memory location. (We need to cast the
// offset to a pointer value, otherwise this wont work)
ptr = (void*)offset;
}
// AFTER reading the file (deserialise), we need to convert
// that integer offset back into a valid memory address...
void refix()
{
// grab start of struct in memory
char* startOfFile = (char*)this;
// and add the offset to the start of the file, to
// get the valid memory location
ptr = startOfFile + ((size_t)ptr);
}
};
it seems that you have a void* ptr
and sometype* script->mem
, you cast them both to char*
and subtract one from another, then you cast the result to void*