зеркало из https://github.com/mozilla/gecko-dev.git
56 строки
1.3 KiB
C++
56 строки
1.3 KiB
C++
|
/*
|
||
|
typeinfo.cpp
|
||
|
|
||
|
Speculatively use RTTI on a random object. If it contains a pointer at offset 0
|
||
|
that is in the current process' address space, and that so on, then attempt to
|
||
|
use C++ RTTI's typeid operation to obtain the name of the type.
|
||
|
|
||
|
by Patrick C. Beard.
|
||
|
*/
|
||
|
|
||
|
#include <typeinfo>
|
||
|
#include <Processes.h>
|
||
|
|
||
|
extern "C" const char* getTypeName(void* ptr);
|
||
|
|
||
|
class AddressSpace {
|
||
|
public:
|
||
|
AddressSpace();
|
||
|
Boolean contains(void* ptr);
|
||
|
private:
|
||
|
ProcessInfoRec mInfo;
|
||
|
};
|
||
|
|
||
|
AddressSpace::AddressSpace()
|
||
|
{
|
||
|
ProcessSerialNumber psn = { 0, kCurrentProcess };
|
||
|
mInfo.processInfoLength = sizeof(mInfo);
|
||
|
::GetProcessInformation(&psn, &mInfo);
|
||
|
}
|
||
|
|
||
|
Boolean AddressSpace::contains(void* ptr)
|
||
|
{
|
||
|
UInt32 start = UInt32(mInfo.processLocation);
|
||
|
return (UInt32(ptr) >= start && UInt32(ptr) < (start + mInfo.processSize));
|
||
|
}
|
||
|
|
||
|
class IUnknown {
|
||
|
virtual long QueryInterface() = 0;
|
||
|
virtual long AddRef() = 0;
|
||
|
virtual long Release() = 0;
|
||
|
};
|
||
|
|
||
|
const char* getTypeName(void* ptr)
|
||
|
{
|
||
|
// construct only one of these per process.
|
||
|
static AddressSpace space;
|
||
|
|
||
|
// sanity check the vtable pointer, before trying to use RTTI on the object.
|
||
|
void** vt = *(void***)ptr;
|
||
|
if (space.contains(vt) && space.contains(*vt)) {
|
||
|
IUnknown* u = static_cast<IUnknown*>(ptr);
|
||
|
return typeid(*u).name();
|
||
|
}
|
||
|
return "void*";
|
||
|
}
|