From 635e1998eee7ba82ececf78e5b7840a0d5543486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Fri, 25 Mar 2011 06:40:33 +0100 Subject: [PATCH] Stop DFVector from accessing VersionInfo in the constructor (slight optimization). --- library/DFProcess-linux-SHM.cpp | 7 +++++++ library/DFProcess-linux-wine.cpp | 8 ++++++++ library/DFProcess-linux.cpp | 9 +++++++++ library/DFProcess-windows-SHM.cpp | 6 ++++++ library/DFProcess-windows.cpp | 8 ++++++++ library/include/dfhack/DFProcess.h | 9 +++++++++ library/include/dfhack/DFVector.h | 30 ++++++++++++++++++------------ library/modules/Maps.cpp | 16 +++++++++++----- library/private/LinuxProcess.h | 8 ++++---- library/private/SHMProcess.h | 4 ++++ 10 files changed, 84 insertions(+), 21 deletions(-) diff --git a/library/DFProcess-linux-SHM.cpp b/library/DFProcess-linux-SHM.cpp index b23132066..cbc312d18 100644 --- a/library/DFProcess-linux-SHM.cpp +++ b/library/DFProcess-linux-SHM.cpp @@ -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(); diff --git a/library/DFProcess-linux-wine.cpp b/library/DFProcess-linux-wine.cpp index 29fcd9b75..ea5c1bcc4 100644 --- a/library/DFProcess-linux-wine.cpp +++ b/library/DFProcess-linux-wine.cpp @@ -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); diff --git a/library/DFProcess-linux.cpp b/library/DFProcess-linux.cpp index b707ab972..bd4515008 100644 --- a/library/DFProcess-linux.cpp +++ b/library/DFProcess-linux.cpp @@ -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; diff --git a/library/DFProcess-windows-SHM.cpp b/library/DFProcess-windows-SHM.cpp index 50c410b39..c36940403 100644 --- a/library/DFProcess-windows-SHM.cpp +++ b/library/DFProcess-windows-SHM.cpp @@ -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); diff --git a/library/DFProcess-windows.cpp b/library/DFProcess-windows.cpp index ac774546d..672286085 100644 --- a/library/DFProcess-windows.cpp +++ b/library/DFProcess-windows.cpp @@ -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 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); diff --git a/library/include/dfhack/DFProcess.h b/library/include/dfhack/DFProcess.h index d7046c132..4b2d01bc1 100644 --- a/library/include/dfhack/DFProcess.h +++ b/library/include/dfhack/DFProcess.h @@ -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; diff --git a/library/include/dfhack/DFVector.h b/library/include/dfhack/DFVector.h index 2eca3f2d8..d6c04eb5d 100644 --- a/library/include/dfhack/DFVector.h +++ b/library/include/dfhack/DFVector.h @@ -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 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; }; }; } diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index c4449c3bb..15b1a3a8c 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -917,46 +917,52 @@ bool Maps::ReadVeins(uint32_t x, uint32_t y, uint32_t z, vector * 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); diff --git a/library/private/LinuxProcess.h b/library/private/LinuxProcess.h index bafe786ac..6ece1c69c 100644 --- a/library/private/LinuxProcess.h +++ b/library/private/LinuxProcess.h @@ -29,16 +29,16 @@ distribution. namespace DFHack { - class LinuxProcessBase : public Process + class LinuxProcessBase : public Process { protected: VersionInfo * my_descriptor; 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(); diff --git a/library/private/SHMProcess.h b/library/private/SHMProcess.h index e10476aad..28b5c6e80 100644 --- a/library/private/SHMProcess.h +++ b/library/private/SHMProcess.h @@ -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); @@ -107,6 +109,8 @@ namespace DFHack bool locked; bool identified; bool useYield; + + uint8_t vector_start; #ifdef LINUX_BUILD pid_t process_ID;