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!!!!
memdescriptor->setParentProcess(self);
identified = true;
vector_start = memdescriptor->getGroup("vector")->getOffset("start");
return true;
}
return false;
@ -368,6 +369,12 @@ bool SHMProcess::detach()
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)
{
if(!d->locked) throw Error::MemoryAccessDenied();

@ -36,6 +36,7 @@ namespace {
class WineProcess : public LinuxProcessBase
{
private:
uint8_t vector_start;
MicrosoftSTL stl;
public:
WineProcess(uint32_t pid, VersionInfoFactory * factory);
@ -54,6 +55,7 @@ namespace {
bool resume();
bool forceresume();
void readSTLVector(const uint32_t address, t_vecTriplet & triplet);
const std::string readSTLString (uint32_t offset);
size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity);
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->setParentProcess(this);
vector_start = my_descriptor->getGroup("vector")->getOffset("start");
stl.init(this);
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)
{
return stl.readSTLString(offset, buffer, bufcapacity);

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

@ -254,6 +254,7 @@ bool SHMProcess::Private::validate(VersionInfoFactory * factory)
memdescriptor = m;
m->setParentProcess(self);
identified = true;
vector_start = memdescriptor->getGroup("vector")->getOffset("start");
CloseHandle(hProcess);
return true;
}
@ -379,6 +380,11 @@ bool SHMProcess::detach()
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)
{
int rtti = Process::readDWord(vptr - 0x4);

@ -42,6 +42,7 @@ namespace
bool attached;
bool suspended;
bool identified;
uint8_t vector_start;
IMAGE_NT_HEADERS pe_header;
IMAGE_SECTION_HEADER * sections;
uint32_t base;
@ -74,6 +75,7 @@ namespace
void read( 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);
size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity);
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);
// keep track of created memory_info object so we can destroy it later
my_descriptor->setParentProcess(this);
vector_start = my_descriptor->getGroup("vector")->getOffset("start");
// TODO: detect errors in thread enumeration
vector<uint32_t> threads;
@ -517,6 +520,11 @@ const string NormalProcess::readCString (const uint32_t offset)
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)
{
return stl.readSTLString(offset, buffer, bufcapacity);

@ -34,6 +34,7 @@ namespace DFHack
class VersionInfo;
class Process;
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)
@ -84,6 +85,12 @@ namespace DFHack
bool valid;
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
* \ingroup grp_context
@ -154,6 +161,8 @@ namespace DFHack
virtual size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) = 0;
/// write an STL string
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
virtual std::string readClassName(uint32_t vptr) = 0;

@ -27,30 +27,26 @@ distribution.
#include "DFPragma.h"
#include "DFExport.h"
#include "VersionInfo.h"
#include "DFProcess.h"
namespace DFHack
{
class VersionInfo;
class Process;
template <class T>
class DFHACK_EXPORT DfVector
{
private:
uint32_t _start;// starting offset
t_vecTriplet t;
uint32_t _size;// vector size
T * data; // cached data
public:
DfVector(Process * p, uint32_t address)
{
uint32_t triplet[3];
VersionInfo * mem = p->getDescriptor();
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];
p->readSTLVector(address,t);
uint32_t byte_size = t.end - t.start;
_size = byte_size / sizeof(T);
data = new T[_size];
p->read(_start,byte_size, (uint8_t *)data);
p->read(t.start,byte_size, (uint8_t *)data);
};
DfVector()
{
@ -82,7 +78,17 @@ namespace DFHack
// get vector 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
uint32_t temp = p_veins[i];
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)
p->read (temp, sizeof(t_vein), (uint8_t *) &v);
v.address_of = temp;
// store it in the vector
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)
p->read (temp, sizeof(t_frozenliquidvein), (uint8_t *) &fv);
fv.address_of = temp;
// store it in the vector
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)
p->read (temp, sizeof(t_spattervein), (uint8_t *) &sv);
sv.address_of = temp;
// store it in the vector
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)
p->read (temp, sizeof(t_grassvein), (uint8_t *) &gv);
gv.address_of = temp;
// store it in the vector
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)
p->read (temp, sizeof(t_worldconstruction), (uint8_t *) &wcv);
wcv.address_of = temp;
// store it in the vector
constructions->push_back (wcv);
}
// previously unseen type of vein
else
{
string cname = p->readClassName(type);

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

@ -69,6 +69,8 @@ namespace DFHack
const std::string readSTLString (uint32_t offset);
size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity);
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
std::string readClassName(uint32_t vptr);
@ -108,6 +110,8 @@ namespace DFHack
bool identified;
bool useYield;
uint8_t vector_start;
#ifdef LINUX_BUILD
pid_t process_ID;
int shm_ID;