Stop DFVector from accessing VersionInfo in the constructor (slight optimization).

develop
Petr Mrázek 2011-03-25 06:40:33 +01:00
parent 820767d701
commit 635e1998ee
10 changed files with 84 additions and 21 deletions

@ -245,6 +245,7 @@ bool SHMProcess::Private::validate(VersionInfoFactory * factory)
// FIXME: BIG BAD BUG RIGHT HERE!!!! // FIXME: BIG BAD BUG RIGHT HERE!!!!
memdescriptor->setParentProcess(self); memdescriptor->setParentProcess(self);
identified = true; identified = true;
vector_start = memdescriptor->getGroup("vector")->getOffset("start");
return true; return true;
} }
return false; return false;
@ -368,6 +369,12 @@ bool SHMProcess::detach()
return false; return false;
} }
void SHMProcess::readSTLVector(const uint32_t address, t_vecTriplet & triplet)
{
read(address + d->vector_start, sizeof(triplet), (uint8_t *) &triplet);
}
string SHMProcess::readClassName (uint32_t vptr) string SHMProcess::readClassName (uint32_t vptr)
{ {
if(!d->locked) throw Error::MemoryAccessDenied(); if(!d->locked) throw Error::MemoryAccessDenied();

@ -36,6 +36,7 @@ namespace {
class WineProcess : public LinuxProcessBase class WineProcess : public LinuxProcessBase
{ {
private: private:
uint8_t vector_start;
MicrosoftSTL stl; MicrosoftSTL stl;
public: public:
WineProcess(uint32_t pid, VersionInfoFactory * factory); WineProcess(uint32_t pid, VersionInfoFactory * factory);
@ -54,6 +55,7 @@ namespace {
bool resume(); bool resume();
bool forceresume(); bool forceresume();
void readSTLVector(const uint32_t address, t_vecTriplet & triplet);
const std::string readSTLString (uint32_t offset); const std::string readSTLString (uint32_t offset);
size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity); size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity);
void writeSTLString(const uint32_t address, const std::string writeString){}; void writeSTLString(const uint32_t address, const std::string writeString){};
@ -123,6 +125,7 @@ WineProcess::WineProcess(uint32_t pid, VersionInfoFactory * factory) : LinuxProc
{ {
my_descriptor = new VersionInfo(*vinfo); my_descriptor = new VersionInfo(*vinfo);
my_descriptor->setParentProcess(this); my_descriptor->setParentProcess(this);
vector_start = my_descriptor->getGroup("vector")->getOffset("start");
stl.init(this); stl.init(this);
identified = true; identified = true;
} }
@ -131,6 +134,11 @@ WineProcess::WineProcess(uint32_t pid, VersionInfoFactory * factory) : LinuxProc
} }
} }
void WineProcess::readSTLVector(const uint32_t address, t_vecTriplet & triplet)
{
read(address + vector_start, sizeof(triplet), (uint8_t *) &triplet);
}
size_t WineProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) size_t WineProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity)
{ {
return stl.readSTLString(offset, buffer, bufcapacity); return stl.readSTLString(offset, buffer, bufcapacity);

@ -33,6 +33,8 @@ using namespace DFHack;
namespace { namespace {
class NormalProcess : public LinuxProcessBase class NormalProcess : public LinuxProcessBase
{ {
private:
uint8_t vector_start;
public: public:
NormalProcess(uint32_t pid, VersionInfoFactory * known_versions); NormalProcess(uint32_t pid, VersionInfoFactory * known_versions);
~NormalProcess() ~NormalProcess()
@ -50,6 +52,7 @@ namespace {
bool resume(); bool resume();
bool forceresume(); bool forceresume();
void readSTLVector(const uint32_t address, t_vecTriplet & triplet);
const std::string readSTLString (uint32_t offset); const std::string readSTLString (uint32_t offset);
size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity); size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity);
void writeSTLString(const uint32_t address, const std::string writeString){}; void writeSTLString(const uint32_t address, const std::string writeString){};
@ -104,6 +107,7 @@ NormalProcess::NormalProcess(uint32_t pid, VersionInfoFactory * known_versions)
{ {
my_descriptor = new VersionInfo(*vinfo); my_descriptor = new VersionInfo(*vinfo);
my_descriptor->setParentProcess(this); my_descriptor->setParentProcess(this);
vector_start = my_descriptor->getGroup("vector")->getOffset("start");
identified = true; identified = true;
} }
} }
@ -127,6 +131,11 @@ size_t NormalProcess::readSTLString (uint32_t offset, char * buffer, size_t bufc
return read_real; return read_real;
} }
void NormalProcess::readSTLVector(const uint32_t address, t_vecTriplet & triplet)
{
read(address + vector_start, sizeof(triplet), (uint8_t *) &triplet);
}
const string NormalProcess::readSTLString (uint32_t offset) const string NormalProcess::readSTLString (uint32_t offset)
{ {
_Rep_base header; _Rep_base header;

@ -254,6 +254,7 @@ bool SHMProcess::Private::validate(VersionInfoFactory * factory)
memdescriptor = m; memdescriptor = m;
m->setParentProcess(self); m->setParentProcess(self);
identified = true; identified = true;
vector_start = memdescriptor->getGroup("vector")->getOffset("start");
CloseHandle(hProcess); CloseHandle(hProcess);
return true; return true;
} }
@ -379,6 +380,11 @@ bool SHMProcess::detach()
return true; return true;
} }
void SHMProcess::readSTLVector(const uint32_t address, t_vecTriplet & triplet)
{
read(address + d->vector_start, sizeof(triplet), (uint8_t *) &triplet);
}
string SHMProcess::readClassName (uint32_t vptr) string SHMProcess::readClassName (uint32_t vptr)
{ {
int rtti = Process::readDWord(vptr - 0x4); int rtti = Process::readDWord(vptr - 0x4);

@ -42,6 +42,7 @@ namespace
bool attached; bool attached;
bool suspended; bool suspended;
bool identified; bool identified;
uint8_t vector_start;
IMAGE_NT_HEADERS pe_header; IMAGE_NT_HEADERS pe_header;
IMAGE_SECTION_HEADER * sections; IMAGE_SECTION_HEADER * sections;
uint32_t base; uint32_t base;
@ -74,6 +75,7 @@ namespace
void read( uint32_t address, uint32_t length, uint8_t* buffer); void read( uint32_t address, uint32_t length, uint8_t* buffer);
void write(uint32_t address, uint32_t length, uint8_t* buffer); void write(uint32_t address, uint32_t length, uint8_t* buffer);
void readSTLVector(const uint32_t address, t_vecTriplet & triplet);
const std::string readSTLString (uint32_t offset); const std::string readSTLString (uint32_t offset);
size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity); size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity);
void writeSTLString(const uint32_t address, const std::string writeString){}; void writeSTLString(const uint32_t address, const std::string writeString){};
@ -164,6 +166,7 @@ NormalProcess::NormalProcess(uint32_t pid, VersionInfoFactory * factory)
my_descriptor->RebaseAll(base); my_descriptor->RebaseAll(base);
// keep track of created memory_info object so we can destroy it later // keep track of created memory_info object so we can destroy it later
my_descriptor->setParentProcess(this); my_descriptor->setParentProcess(this);
vector_start = my_descriptor->getGroup("vector")->getOffset("start");
// TODO: detect errors in thread enumeration // TODO: detect errors in thread enumeration
vector<uint32_t> threads; vector<uint32_t> threads;
@ -517,6 +520,11 @@ const string NormalProcess::readCString (const uint32_t offset)
return temp; return temp;
} }
void NormalProcess::readSTLVector(const uint32_t address, t_vecTriplet & triplet)
{
read(address + vector_start, sizeof(triplet), (uint8_t *) &triplet);
}
size_t NormalProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) size_t NormalProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity)
{ {
return stl.readSTLString(offset, buffer, bufcapacity); return stl.readSTLString(offset, buffer, bufcapacity);

@ -34,6 +34,7 @@ namespace DFHack
class VersionInfo; class VersionInfo;
class Process; class Process;
class Window; class Window;
class DFVector;
/** /**
* A type for storing an extended OS Process ID (combines PID and the time the process was started for unique identification) * A type for storing an extended OS Process ID (combines PID and the time the process was started for unique identification)
@ -84,6 +85,12 @@ namespace DFHack
bool valid; bool valid;
uint8_t * buffer; uint8_t * buffer;
}; };
struct t_vecTriplet
{
uint32_t start;
uint32_t end;
uint32_t alloc_end;
};
/** /**
* Allows low-level access to the memory of an OS process. OS processes can be enumerated by \ref ProcessEnumerator * Allows low-level access to the memory of an OS process. OS processes can be enumerated by \ref ProcessEnumerator
* \ingroup grp_context * \ingroup grp_context
@ -154,6 +161,8 @@ namespace DFHack
virtual size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) = 0; virtual size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) = 0;
/// write an STL string /// write an STL string
virtual void writeSTLString(const uint32_t address, const std::string writeString) = 0; virtual void writeSTLString(const uint32_t address, const std::string writeString) = 0;
/// read a STL vector
virtual void readSTLVector(const uint32_t address, t_vecTriplet & triplet) = 0;
/// get class name of an object with rtti/type info /// get class name of an object with rtti/type info
virtual std::string readClassName(uint32_t vptr) = 0; virtual std::string readClassName(uint32_t vptr) = 0;

@ -27,30 +27,26 @@ distribution.
#include "DFPragma.h" #include "DFPragma.h"
#include "DFExport.h" #include "DFExport.h"
#include "VersionInfo.h"
#include "DFProcess.h"
namespace DFHack namespace DFHack
{ {
class VersionInfo;
class Process;
template <class T> template <class T>
class DFHACK_EXPORT DfVector class DFHACK_EXPORT DfVector
{ {
private: private:
uint32_t _start;// starting offset t_vecTriplet t;
uint32_t _size;// vector size uint32_t _size;// vector size
T * data; // cached data T * data; // cached data
public: public:
DfVector(Process * p, uint32_t address) DfVector(Process * p, uint32_t address)
{ {
uint32_t triplet[3]; p->readSTLVector(address,t);
VersionInfo * mem = p->getDescriptor(); uint32_t byte_size = t.end - t.start;
uint32_t offs = mem->getGroup("vector")->getOffset("start");
p->read(address + offs, sizeof(triplet), (uint8_t *) &triplet);
_start = triplet[0];
uint32_t byte_size = triplet[1] - triplet[0];
_size = byte_size / sizeof(T); _size = byte_size / sizeof(T);
data = new T[_size]; data = new T[_size];
p->read(_start,byte_size, (uint8_t *)data); p->read(t.start,byte_size, (uint8_t *)data);
}; };
DfVector() DfVector()
{ {
@ -82,7 +78,17 @@ namespace DFHack
// get vector start // get vector start
inline uint32_t start () inline uint32_t start ()
{ {
return _start; return t.start;
};
// get vector end
inline uint32_t end ()
{
return t.end;
};
// get vector start
inline const uint32_t alloc_end ()
{
return t.alloc_end;
}; };
}; };
} }

@ -917,46 +917,52 @@ bool Maps::ReadVeins(uint32_t x, uint32_t y, uint32_t z, vector <t_vein>* veins,
// read the vein pointer from the vector // read the vein pointer from the vector
uint32_t temp = p_veins[i]; uint32_t temp = p_veins[i];
uint32_t type = p->readDWord(temp); uint32_t type = p->readDWord(temp);
if(veins && type == off.vein_mineral_vptr) if(type == off.vein_mineral_vptr)
{ {
if(!veins) continue;
// read the vein data (dereference pointer) // read the vein data (dereference pointer)
p->read (temp, sizeof(t_vein), (uint8_t *) &v); p->read (temp, sizeof(t_vein), (uint8_t *) &v);
v.address_of = temp; v.address_of = temp;
// store it in the vector // store it in the vector
veins->push_back (v); veins->push_back (v);
} }
else if(ices && type == off.vein_ice_vptr) else if(type == off.vein_ice_vptr)
{ {
if(!ices) continue;
// read the ice vein data (dereference pointer) // read the ice vein data (dereference pointer)
p->read (temp, sizeof(t_frozenliquidvein), (uint8_t *) &fv); p->read (temp, sizeof(t_frozenliquidvein), (uint8_t *) &fv);
fv.address_of = temp; fv.address_of = temp;
// store it in the vector // store it in the vector
ices->push_back (fv); ices->push_back (fv);
} }
else if(splatter && type == off.vein_spatter_vptr) else if(type == off.vein_spatter_vptr)
{ {
if(!splatter) continue;
// read the splatter vein data (dereference pointer) // read the splatter vein data (dereference pointer)
p->read (temp, sizeof(t_spattervein), (uint8_t *) &sv); p->read (temp, sizeof(t_spattervein), (uint8_t *) &sv);
sv.address_of = temp; sv.address_of = temp;
// store it in the vector // store it in the vector
splatter->push_back (sv); splatter->push_back (sv);
} }
else if(grass && type == off.vein_grass_vptr) else if(type == off.vein_grass_vptr)
{ {
if(!grass) continue;
// read the splatter vein data (dereference pointer) // read the splatter vein data (dereference pointer)
p->read (temp, sizeof(t_grassvein), (uint8_t *) &gv); p->read (temp, sizeof(t_grassvein), (uint8_t *) &gv);
gv.address_of = temp; gv.address_of = temp;
// store it in the vector // store it in the vector
grass->push_back (gv); grass->push_back (gv);
} }
else if(constructions && type == off.vein_worldconstruction_vptr) else if(type == off.vein_worldconstruction_vptr)
{ {
if(!constructions) continue;
// read the splatter vein data (dereference pointer) // read the splatter vein data (dereference pointer)
p->read (temp, sizeof(t_worldconstruction), (uint8_t *) &wcv); p->read (temp, sizeof(t_worldconstruction), (uint8_t *) &wcv);
wcv.address_of = temp; wcv.address_of = temp;
// store it in the vector // store it in the vector
constructions->push_back (wcv); constructions->push_back (wcv);
} }
// previously unseen type of vein
else else
{ {
string cname = p->readClassName(type); string cname = p->readClassName(type);

@ -36,9 +36,9 @@ namespace DFHack
pid_t my_pid; pid_t my_pid;
string memFile; string memFile;
int memFileHandle; int memFileHandle;
bool attached; bool attached:1;
bool suspended; bool suspended:1;
bool identified; bool identified:1;
public: public:
LinuxProcessBase(uint32_t pid); LinuxProcessBase(uint32_t pid);
~LinuxProcessBase(); ~LinuxProcessBase();

@ -69,6 +69,8 @@ namespace DFHack
const std::string readSTLString (uint32_t offset); const std::string readSTLString (uint32_t offset);
size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity); size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity);
void writeSTLString(const uint32_t address, const std::string writeString); void writeSTLString(const uint32_t address, const std::string writeString);
void readSTLVector(const uint32_t address, t_vecTriplet & triplet);
// get class name of an object with rtti/type info // get class name of an object with rtti/type info
std::string readClassName(uint32_t vptr); std::string readClassName(uint32_t vptr);
@ -108,6 +110,8 @@ namespace DFHack
bool identified; bool identified;
bool useYield; bool useYield;
uint8_t vector_start;
#ifdef LINUX_BUILD #ifdef LINUX_BUILD
pid_t process_ID; pid_t process_ID;
int shm_ID; int shm_ID;