From 1e04722a63de619be2d6ec983a9fc9ebe63cf3d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Mon, 22 Feb 2010 23:34:20 +0100 Subject: [PATCH] Refactor of memory_info class, now with more d-pointer --- examples/creaturedump.cpp | 6 +- examples/hotkeynotedump.cpp | 2 +- examples/materialtest.cpp | 2 +- examples/renamer.cpp | 6 +- library/DFHackAPI.cpp | 20 +- library/DFHackAPI.h | 2 +- library/DFMemInfo.cpp | 341 +++++++++++++++----------- library/DFMemInfo.h | 38 +-- library/DFMemInfoManager.cpp | 49 ++-- library/DFMemInfoManager.h | 6 +- library/DFProcess-linux-SHM.cpp | 12 +- library/DFProcess-linux-wine.cpp | 12 +- library/DFProcess-linux.cpp | 14 +- library/DFProcess-windows-SHM.cpp | 8 +- library/DFProcess-windows.cpp | 12 +- library/DFProcess.h | 6 +- library/DFProcessEnumerator-linux.cpp | 3 - 17 files changed, 295 insertions(+), 244 deletions(-) diff --git a/examples/creaturedump.cpp b/examples/creaturedump.cpp index 2dc52028b..77743cc63 100644 --- a/examples/creaturedump.cpp +++ b/examples/creaturedump.cpp @@ -161,7 +161,7 @@ int main (void) DF.ReadMetalMatgloss(mat.metalMat); DF.ReadCreatureMatgloss(mat.creatureMat); - DFHack::memory_info mem = DF.getMemoryInfo(); + DFHack::memory_info *mem = DF.getMemoryInfo(); // get stone matgloss mapping if(!DF.ReadCreatureMatgloss(creaturestypes)) { @@ -229,14 +229,14 @@ int main (void) cout << endl; addendl = false; } - cout << "profession: " << mem.getProfession(temp.profession) << "(" << (int) temp.profession << ")"; + cout << "profession: " << mem->getProfession(temp.profession) << "(" << (int) temp.profession << ")"; if(temp.custom_profession[0]) { cout << ", custom profession: " << temp.custom_profession; } if(temp.current_job.active) { - cout << ", current job: " << mem.getJob(temp.current_job.jobId); + cout << ", current job: " << mem->getJob(temp.current_job.jobId); } cout << endl; cout << "happiness: " << temp.happiness << ", strength: " << temp.strength << ", agility: " diff --git a/examples/hotkeynotedump.cpp b/examples/hotkeynotedump.cpp index 9685e33d5..50e695c07 100644 --- a/examples/hotkeynotedump.cpp +++ b/examples/hotkeynotedump.cpp @@ -21,7 +21,7 @@ int main (void) return 1; } - DFHack::memory_info mem = DF.getMemoryInfo(); + DFHack::memory_info * mem = DF.getMemoryInfo(); // get stone matgloss mapping uint32_t numNotes; if(!DF.InitReadNotes(numNotes)) diff --git a/examples/materialtest.cpp b/examples/materialtest.cpp index cb0421610..d0bb7bffc 100644 --- a/examples/materialtest.cpp +++ b/examples/materialtest.cpp @@ -20,7 +20,7 @@ int main (void) return 1; } vector Woods; - DF.ReadPlantMatgloss(Woods); + DF.ReadWoodMatgloss(Woods); vector Plants; DF.ReadPlantMatgloss(Plants); diff --git a/examples/renamer.cpp b/examples/renamer.cpp index 9171d0eaf..2a374d014 100644 --- a/examples/renamer.cpp +++ b/examples/renamer.cpp @@ -317,7 +317,7 @@ int main (void) return 1; } - DFHack::memory_info mem = DF.getMemoryInfo(); + DFHack::memory_info * mem = DF.getMemoryInfo(); if (!DF.ReadCreatureMatgloss(creaturestypes)) { @@ -434,11 +434,11 @@ start: // I have the writeString function do nothing for normal mode if (commandString == "pzyn") // change nickname { - p->writeSTLString(toChange.origin+mem.getOffset("creature_nick_name"),changeString); + p->writeSTLString(toChange.origin+mem->getOffset("creature_nick_name"),changeString); } else { - p->writeSTLString(toChange.origin+mem.getOffset("creature_custom_profession"),changeString); + p->writeSTLString(toChange.origin+mem->getOffset("creature_custom_profession"),changeString); } } DF.Suspend(); diff --git a/library/DFHackAPI.cpp b/library/DFHackAPI.cpp index 2c5b8693b..278ee3942 100644 --- a/library/DFHackAPI.cpp +++ b/library/DFHackAPI.cpp @@ -395,6 +395,7 @@ bool API::ReadVeins(uint32_t x, uint32_t y, uint32_t z, vector & veins, // read the vein pointer from the vector uint32_t temp = * (uint32_t *) p_veins[i]; uint32_t type = g_pProcess->readDWord(temp); +try_again: if(type == d->vein_mineral_vptr) { // read the vein data (dereference pointer) @@ -410,6 +411,21 @@ bool API::ReadVeins(uint32_t x, uint32_t y, uint32_t z, vector & veins, // store it in the vector ices.push_back (fv); } + //#define ___FIND_ + #ifdef ___FIND_THEM + else if(g_pProcess->readClassName(type) == "block_square_event_frozen_liquid") + { + d->vein_ice_vptr = type; + cout << "block_square_event_frozen_liquid : 0x" << hex << type << endl; + goto try_again; + } + else if(g_pProcess->readClassName(type) == "block_square_event_mineral") + { + d->vein_mineral_vptr = type; + cout << "block_square_event_mineral : 0x" << hex << type << endl; + goto try_again; + } + #endif } return true; } @@ -1420,9 +1436,9 @@ bool API::getClassIDMapping (vector & objecttypes) return false; } -memory_info API::getMemoryInfo() +memory_info *API::getMemoryInfo() { - return *d->offset_descriptor; + return d->offset_descriptor; } Process * API::getProcess() { diff --git a/library/DFHackAPI.h b/library/DFHackAPI.h index 3dbe045ed..313c5ec96 100644 --- a/library/DFHackAPI.h +++ b/library/DFHackAPI.h @@ -229,7 +229,7 @@ namespace DFHack // wrapper for meminfo method of the same name bool getClassIDMapping (vector & objecttypes); - memory_info getMemoryInfo(); + memory_info *getMemoryInfo(); Process * getProcess(); DFWindow * getWindow(); /* diff --git a/library/DFMemInfo.cpp b/library/DFMemInfo.cpp index a1745a977..be2671a52 100644 --- a/library/DFMemInfo.cpp +++ b/library/DFMemInfo.cpp @@ -23,31 +23,95 @@ distribution. */ #include "DFCommonInternal.h" - +/* +#if !defined(NDEBUG) +#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING +#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE +#endif + +#include +#include +#include +#include +#include +#include +#include + +using boost::multi_index_container; +using namespace boost::multi_index; +*/ using namespace DFHack; + +/* +* Common data types +*/ +struct t_class +{ + string classname; + uint32_t vtable; + bool is_multiclass; + uint32_t multi_index; + uint32_t assign;// index to typeclass array if multiclass. return value if not. + uint32_t type_offset; // offset of type data for multiclass +}; + +struct t_type +{ + string classname; + uint32_t assign; + uint32_t type; +}; + + +/* + * Private data + */ +class memory_info::Private +{ + public: + map addresses; + map offsets; + map hexvals; + map strings; + + vector professions; + vector jobs; + vector skills; + vector< vector > traits; + map labors; + + vector classes; + vector > classsubtypes; + int32_t base; + uint32_t classindex; + string version; + OSType OS; +}; + memory_info::memory_info() +:d(new Private) { - base = 0; - classindex = 0; + d->base = 0; + d->classindex = 0; } void memory_info::setVersion(const char * v) { - version = v; + d->version = v; } void memory_info::setVersion(const string &v) { - version = v; + d->version = v; } string memory_info::getVersion() { - return version; + return d->version; } @@ -55,22 +119,22 @@ void memory_info::setOS(const char *os) { string oss = os; if(oss == "windows") - OS = OS_WINDOWS; + d->OS = OS_WINDOWS; else if(oss == "linux") - OS = OS_LINUX; + d->OS = OS_LINUX; else - OS = OS_BAD; + d->OS = OS_BAD; } void memory_info::setOS(const string &os) { if(os == "windows") - OS = OS_WINDOWS; + d->OS = OS_WINDOWS; else if(os == "linux") - OS = OS_LINUX; + d->OS = OS_LINUX; else - OS = OS_BAD; + d->OS = OS_BAD; } @@ -78,117 +142,118 @@ void memory_info::setOS(OSType os) { if(os >= OS_WINDOWS && os < OS_BAD) { - OS = os; + d->OS = os; return; } - OS = OS_BAD; + d->OS = OS_BAD; } memory_info::OSType memory_info::getOS() const { - return OS; + return d->OS; } // copy constructor memory_info::memory_info(const memory_info &old) -{ - version = old.version; - OS = old.OS; - addresses = old.addresses; - offsets = old.offsets; - hexvals = old.hexvals; - strings = old.strings; - base = old.base; - classes = old.classes; - classsubtypes = old.classsubtypes; - classindex = old.classindex; - professions = old.professions; - jobs = old.jobs; - skills = old.skills; - traits = old.traits; - labors = old.labors; +:d(new Private) +{ + d->version = old.d->version; + d->OS = old.d->OS; + d->addresses = old.d->addresses; + d->offsets = old.d->offsets; + d->hexvals = old.d->hexvals; + d->strings = old.d->strings; + d->base = old.d->base; + d->classes = old.d->classes; + d->classsubtypes = old.d->classsubtypes; + d->classindex = old.d->classindex; + d->professions = old.d->professions; + d->jobs = old.d->jobs; + d->skills = old.d->skills; + d->traits = old.d->traits; + d->labors = old.d->labors; } uint32_t memory_info::getBase () const { - return base; + return d->base; } void memory_info::setBase (const string &s) { - base = strtol(s.c_str(), NULL, 16); + d->base = strtol(s.c_str(), NULL, 16); } void memory_info::setBase (const uint32_t b) { - base = b; + d->base = b; } void memory_info::setOffset (const string & key, const string & value) { uint32_t offset = strtol(value.c_str(), NULL, 16); - offsets[key] = offset; + d->offsets[key] = offset; } void memory_info::setAddress (const string & key, const string & value) { uint32_t address = strtol(value.c_str(), NULL, 16); - addresses[key] = address; + d->addresses[key] = address; } void memory_info::setHexValue (const string & key, const string & value) { uint32_t hexval = strtol(value.c_str(), NULL, 16); - hexvals[key] = hexval; + d->hexvals[key] = hexval; } void memory_info::setString (const string & key, const string & value) { - strings[key] = value; + d->strings[key] = value; } void memory_info::setLabor(const string & key, const string & value) { uint32_t keyInt = strtol(key.c_str(), NULL, 10); - labors[keyInt] = value; + d->labors[keyInt] = value; } void memory_info::setProfession (const string & key, const string & value) { uint32_t keyInt = strtol(key.c_str(), NULL, 10); - if(professions.size() <= keyInt) + if(d->professions.size() <= keyInt) { - professions.resize(keyInt+1); + d->professions.resize(keyInt+1); } - professions[keyInt] = value; + d->professions[keyInt] = value; } void memory_info::setJob (const string & key, const string & value) { uint32_t keyInt = strtol(key.c_str(), NULL, 10); - if(jobs.size() <= keyInt) + if(d->jobs.size() <= keyInt) { - jobs.resize(keyInt+1); + d->jobs.resize(keyInt+1); } - jobs[keyInt] = value; + d->jobs[keyInt] = value; } void memory_info::setSkill (const string & key, const string & value) { uint32_t keyInt = strtol(key.c_str(), NULL, 10); - if(skills.size() <= keyInt){ - skills.resize(keyInt+1); + if(d->skills.size() <= keyInt){ + d->skills.resize(keyInt+1); } - skills[keyInt] = value; + d->skills[keyInt] = value; } void memory_info::setTrait(const string & key, @@ -201,39 +266,39 @@ void memory_info::setTrait(const string & key, const string & five) { uint32_t keyInt = strtol(key.c_str(), NULL, 10); - if(traits.size() <= keyInt) + if(d->traits.size() <= keyInt) { - traits.resize(keyInt+1); + d->traits.resize(keyInt+1); } - traits[keyInt].push_back(zero); - traits[keyInt].push_back(one); - traits[keyInt].push_back(two); - traits[keyInt].push_back(three); - traits[keyInt].push_back(four); - traits[keyInt].push_back(five); - traits[keyInt].push_back(value); + d->traits[keyInt].push_back(zero); + d->traits[keyInt].push_back(one); + d->traits[keyInt].push_back(two); + d->traits[keyInt].push_back(three); + d->traits[keyInt].push_back(four); + d->traits[keyInt].push_back(five); + d->traits[keyInt].push_back(value); } // FIXME: next three methods should use some kind of custom container so it doesn't have to search so much. void memory_info::setClass (const char * name, const char * vtable) { - for (uint32_t i=0; iclasses.size(); i++) { - if(classes[i].classname == name) + if(d->classes[i].classname == name) { - classes[i].vtable = strtol(vtable, NULL, 16); + d->classes[i].vtable = strtol(vtable, NULL, 16); return; } } t_class cls; - cls.assign = classindex; + cls.assign = d->classindex; cls.classname = name; cls.is_multiclass = false; cls.type_offset = 0; - classindex++; + d->classindex++; cls.vtable = strtol(vtable, NULL, 16); - classes.push_back(cls); + d->classes.push_back(cls); //cout << "class " << name << ", assign " << cls.assign << ", vtable " << cls.vtable << endl; } @@ -241,40 +306,40 @@ void memory_info::setClass (const char * name, const char * vtable) // find old entry by name, rewrite, return its multi index. otherwise make a new one, append an empty vector of t_type to classtypes, return its index. uint32_t memory_info::setMultiClass (const char * name, const char * vtable, const char * typeoffset) { - for (uint32_t i=0; iclasses.size(); i++) { - if(classes[i].classname == name) + if(d->classes[i].classname == name) { // vtable and typeoffset can be left out from the xml definition when there's already a named multiclass if(vtable != NULL) - classes[i].vtable = strtol(vtable, NULL, 16); + d->classes[i].vtable = strtol(vtable, NULL, 16); if(typeoffset != NULL) - classes[i].type_offset = strtol(typeoffset, NULL, 16); - return classes[i].multi_index; + d->classes[i].type_offset = strtol(typeoffset, NULL, 16); + return d->classes[i].multi_index; } } //FIXME: add checking for vtable and typeoffset here. they HAVE to be valid. maybe change the return value into a bool and pass in multi index by reference? t_class cls; - cls.assign = classindex; + cls.assign = d->classindex; cls.classname = name; cls.is_multiclass = true; cls.type_offset = strtol(typeoffset, NULL, 16); cls.vtable = strtol(vtable, NULL, 16); - cls.multi_index = classsubtypes.size(); - classes.push_back(cls); - classindex++; + cls.multi_index = d->classsubtypes.size(); + d->classes.push_back(cls); + d->classindex++; vector thistypes; - classsubtypes.push_back(thistypes); + d->classsubtypes.push_back(thistypes); //cout << "multiclass " << name << ", assign " << cls.assign << ", vtable " << cls.vtable << endl; - return classsubtypes.size() - 1; + return d->classsubtypes.size() - 1; } void memory_info::setMultiClassChild (uint32_t multi_index, const char * name, const char * type) { - vector & vec = classsubtypes[multi_index]; + vector & vec = d->classsubtypes[multi_index]; for (uint32_t i=0; iclassindex; mcc.classname = name; mcc.type = strtol(type, NULL, 16); vec.push_back(mcc); - classindex++; + d->classindex++; //cout << " classtype " << name << ", assign " << mcc.assign << ", vtable " << mcc.type << endl; } @@ -298,15 +363,15 @@ bool memory_info::resolveClassId(uint32_t address, int32_t & classid) { uint32_t vtable = g_pProcess->readDWord(address); // FIXME: stupid search. we need a better container - for(uint32_t i = 0;i< classes.size();i++) + for(uint32_t i = 0;i< d->classes.size();i++) { - if(classes[i].vtable == vtable) // got class + if(d->classes[i].vtable == vtable) // got class { // if it is a multiclass, try resolving it - if(classes[i].is_multiclass) + if(d->classes[i].is_multiclass) { - vector & vec = classsubtypes[classes[i].multi_index]; - uint32_t type = g_pProcess->readWord(address + classes[i].type_offset); + vector & vec = d->classsubtypes[d->classes[i].multi_index]; + uint32_t type = g_pProcess->readWord(address + d->classes[i].type_offset); //printf ("class %d:%s offset 0x%x\n", i , classes[i].classname.c_str(), classes[i].type_offset); // return typed building if successful for (uint32_t k = 0; k < vec.size();k++) @@ -320,7 +385,7 @@ bool memory_info::resolveClassId(uint32_t address, int32_t & classid) } } // otherwise return the class we found - classid = classes[i].assign; + classid = d->classes[i].assign; return true; } } @@ -332,12 +397,12 @@ bool memory_info::resolveClassId(uint32_t address, int32_t & classid) uint32_t memory_info::getClassVPtr(string classname) { // FIXME: another stupid search. - for(uint32_t i = 0;i< classes.size();i++) + for(uint32_t i = 0;i< d->classes.size();i++) { //if(classes[i].) - if(classes[i].classname == classname) // got class + if(d->classes[i].classname == classname) // got class { - return classes[i].vtable; + return d->classes[i].vtable; } } // we failed to find anything that would match @@ -347,14 +412,14 @@ uint32_t memory_info::getClassVPtr(string classname) // Flatten vtables into a index<->name mapping void memory_info::getClassIDMapping(vector & v_ClassID2ObjName) { - for(uint32_t i = 0;i< classes.size();i++) + for(uint32_t i = 0;i< d->classes.size();i++) { - v_ClassID2ObjName.push_back(classes[i].classname); - if(!classes[i].is_multiclass) + v_ClassID2ObjName.push_back(d->classes[i].classname); + if(!d->classes[i].is_multiclass) { continue; } - vector & vec = classsubtypes[classes[i].multi_index]; + vector & vec = d->classsubtypes[d->classes[i].multi_index]; for (uint32_t k = 0; k < vec.size();k++) { v_ClassID2ObjName.push_back(vec[k].classname); @@ -367,10 +432,10 @@ void memory_info::getClassIDMapping(vector & v_ClassID2ObjName) void memory_info::RebaseAddresses(const int32_t new_base) { map::iterator iter; - int32_t rebase = - (int32_t)base + new_base; - for(iter = addresses.begin(); iter != addresses.end(); iter++) + int32_t rebase = - (int32_t)d->base + new_base; + for(iter = d->addresses.begin(); iter != d->addresses.end(); iter++) { - addresses[iter->first] = iter->second + rebase; + d->addresses[iter->first] = iter->second + rebase; } } @@ -379,10 +444,10 @@ void memory_info::RebaseAddresses(const int32_t new_base) void memory_info::RebaseAll(int32_t new_base) { map::iterator iter; - int32_t rebase = - (int32_t)base + new_base; - for(iter = addresses.begin(); iter != addresses.end(); iter++) + int32_t rebase = - (int32_t)d->base + new_base; + for(iter = d->addresses.begin(); iter != d->addresses.end(); iter++) { - addresses[iter->first] = iter->second + rebase; + d->addresses[iter->first] = iter->second + rebase; } RebaseVTable(rebase); } @@ -392,7 +457,7 @@ void memory_info::RebaseAll(int32_t new_base) void memory_info::RebaseVTable(int32_t offset) { vector::iterator iter; - for(iter = classes.begin(); iter != classes.end(); iter++) + for(iter = d->classes.begin(); iter != d->classes.end(); iter++) { iter->vtable += offset; } @@ -401,9 +466,9 @@ void memory_info::RebaseVTable(int32_t offset) // Get named address uint32_t memory_info::getAddress (const char *key) { - map ::iterator iter = addresses.find(key); + map ::iterator iter = d->addresses.find(key); - if(iter != addresses.end()) + if(iter != d->addresses.end()) { return (*iter).second; } @@ -414,8 +479,8 @@ uint32_t memory_info::getAddress (const char *key) // Get named offset uint32_t memory_info::getOffset (const char *key) { - map ::iterator iter = offsets.find(key); - if(iter != offsets.end()) + map ::iterator iter = d->offsets.find(key); + if(iter != d->offsets.end()) { return (*iter).second; } @@ -425,8 +490,8 @@ uint32_t memory_info::getOffset (const char *key) // Get named numerical value uint32_t memory_info::getHexValue (const char *key) { - map ::iterator iter = hexvals.find(key); - if(iter != hexvals.end()) + map ::iterator iter = d->hexvals.find(key); + if(iter != d->hexvals.end()) { return (*iter).second; } @@ -437,9 +502,9 @@ uint32_t memory_info::getHexValue (const char *key) // Get named address uint32_t memory_info::getAddress (const string &key) { - map ::iterator iter = addresses.find(key); + map ::iterator iter = d->addresses.find(key); - if(iter != addresses.end()) + if(iter != d->addresses.end()) { return (*iter).second; } @@ -450,8 +515,8 @@ uint32_t memory_info::getAddress (const string &key) // Get named offset uint32_t memory_info::getOffset (const string &key) { - map ::iterator iter = offsets.find(key); - if(iter != offsets.end()) + map ::iterator iter = d->offsets.find(key); + if(iter != d->offsets.end()) { return (*iter).second; } @@ -461,8 +526,8 @@ uint32_t memory_info::getOffset (const string &key) // Get named numerical value uint32_t memory_info::getHexValue (const string &key) { - map ::iterator iter = hexvals.find(key); - if(iter != hexvals.end()) + map ::iterator iter = d->hexvals.find(key); + if(iter != d->hexvals.end()) { return (*iter).second; } @@ -472,8 +537,8 @@ uint32_t memory_info::getHexValue (const string &key) // Get named string std::string memory_info::getString (const string &key) { - map ::iterator iter = strings.find(key); - if(iter != strings.end()) + map ::iterator iter = d->strings.find(key); + if(iter != d->strings.end()) { return (*iter).second; } @@ -483,9 +548,9 @@ std::string memory_info::getString (const string &key) // Get Profession string memory_info::getProfession (const uint32_t key) const { - if(professions.size() > key) + if(d->professions.size() > key) { - return professions[key]; + return d->professions[key]; } else { @@ -496,18 +561,18 @@ string memory_info::getProfession (const uint32_t key) const // Get Job string memory_info::getJob (const uint32_t key) const { - if(jobs.size() > key) + if(d->jobs.size() > key) { - return jobs[key]; + return d->jobs[key]; } return string("Job Does Not Exist"); } string memory_info::getSkill (const uint32_t key) const { - if(skills.size() > key) + if(d->skills.size() > key) { - return skills[key]; + return d->skills[key]; } return string("Skill is not Defined"); } @@ -522,7 +587,7 @@ int absolute (int number) string memory_info::getTrait (const uint32_t traitIdx, const uint32_t traitValue) const { - if(traits.size() > traitIdx) + if(d->traits.size() > traitIdx) { int diff = absolute(traitValue-50); if(diff < 10) @@ -530,35 +595,35 @@ string memory_info::getTrait (const uint32_t traitIdx, const uint32_t traitValue return string(""); } if (traitValue >= 91) - return traits[traitIdx][5]; + return d->traits[traitIdx][5]; else if (traitValue >= 76) - return traits[traitIdx][4]; + return d->traits[traitIdx][4]; else if (traitValue >= 61) - return traits[traitIdx][3]; + return d->traits[traitIdx][3]; else if (traitValue >= 25) - return traits[traitIdx][2]; + return d->traits[traitIdx][2]; else if (traitValue >= 10) - return traits[traitIdx][1]; + return d->traits[traitIdx][1]; else - return traits[traitIdx][0]; + return d->traits[traitIdx][0]; } return string("Trait is not Defined"); } string memory_info::getTraitName(const uint32_t traitIdx) const { - if(traits.size() > traitIdx) + if(d->traits.size() > traitIdx) { - return traits[traitIdx][traits[traitIdx].size()-1]; + return d->traits[traitIdx][d->traits[traitIdx].size()-1]; } return string("Trait is not Defined"); } string memory_info::getLabor (const uint32_t laborIdx) { - if(labors.count(laborIdx)) + if(d->labors.count(laborIdx)) { - return labors[laborIdx]; + return d->labors[laborIdx]; } return string(""); } @@ -566,14 +631,14 @@ string memory_info::getLabor (const uint32_t laborIdx) // Reset everything void memory_info::flush() { - base = 0; - addresses.clear(); - offsets.clear(); - strings.clear(); - hexvals.clear(); - classes.clear(); - classsubtypes.clear(); - classindex = 0; - version = ""; - OS = OS_BAD; + d->base = 0; + d->addresses.clear(); + d->offsets.clear(); + d->strings.clear(); + d->hexvals.clear(); + d->classes.clear(); + d->classsubtypes.clear(); + d->classindex = 0; + d->version = ""; + d->OS = OS_BAD; } diff --git a/library/DFMemInfo.h b/library/DFMemInfo.h index f579aba68..5a265bd89 100644 --- a/library/DFMemInfo.h +++ b/library/DFMemInfo.h @@ -34,8 +34,12 @@ distribution. namespace DFHack { + class DFHACK_EXPORT memory_info { + private: + class Private; + Private * d; public: enum OSType { @@ -43,21 +47,6 @@ namespace DFHack OS_LINUX, OS_BAD }; - struct t_class - { - string classname; - uint32_t vtable; - bool is_multiclass; - uint32_t multi_index; - uint32_t assign;// index to typeclass array if multiclass. return value if not. - uint32_t type_offset; // offset of type data for multiclass - }; - struct t_type - { - string classname; - uint32_t assign; - uint32_t type; - }; memory_info(); memory_info(const memory_info&); @@ -123,25 +112,6 @@ namespace DFHack uint32_t getClassVPtr(string classname); void flush(); - - private: - map addresses; - map offsets; - map hexvals; - map strings; - - vector professions; - vector jobs; - vector skills; - vector< vector > traits; - map labors; - - vector classes; - vector > classsubtypes; - int32_t base; - uint32_t classindex; - string version; - OSType OS; }; } #endif // MEMINFO_H_INCLUDED diff --git a/library/DFMemInfoManager.cpp b/library/DFMemInfoManager.cpp index 7c994f7da..beef88934 100644 --- a/library/DFMemInfoManager.cpp +++ b/library/DFMemInfoManager.cpp @@ -25,7 +25,7 @@ distribution. #include "DFCommonInternal.h" using namespace DFHack; -void MemInfoManager::ParseVTable(TiXmlElement* vtable, memory_info& mem) +void MemInfoManager::ParseVTable(TiXmlElement* vtable, memory_info* mem) { TiXmlElement* pClassEntry; TiXmlElement* pClassSubEntry; @@ -34,7 +34,7 @@ void MemInfoManager::ParseVTable(TiXmlElement* vtable, memory_info& mem) if(rebase) { int32_t rebase_offset = strtol(rebase, NULL, 16); - mem.RebaseVTable(rebase_offset); + mem->RebaseVTable(rebase_offset); } // parse vtable entries pClassEntry = vtable->FirstChildElement(); @@ -46,14 +46,14 @@ void MemInfoManager::ParseVTable(TiXmlElement* vtable, memory_info& mem) // it's a simple class if(type== "class") { - mem.setClass(cstr_name, cstr_vtable); + mem->setClass(cstr_name, cstr_vtable); } // it's a multi-type class else if (type == "multiclass") { // get offset of the type variable const char *cstr_typeoffset = pClassEntry->Attribute("typeoffset"); - int mclass = mem.setMultiClass(cstr_name, cstr_vtable, cstr_typeoffset); + int mclass = mem->setMultiClass(cstr_name, cstr_vtable, cstr_typeoffset); // parse class sub-entries pClassSubEntry = pClassEntry->FirstChildElement(); for(;pClassSubEntry;pClassSubEntry=pClassSubEntry->NextSiblingElement()) @@ -64,7 +64,7 @@ void MemInfoManager::ParseVTable(TiXmlElement* vtable, memory_info& mem) // type is a value loaded from type offset cstr_name = pClassSubEntry->Attribute("name"); const char *cstr_value = pClassSubEntry->Attribute("type"); - mem.setMultiClassChild(mclass,cstr_name,cstr_value); + mem->setMultiClassChild(mclass,cstr_name,cstr_value); } } } @@ -73,14 +73,13 @@ void MemInfoManager::ParseVTable(TiXmlElement* vtable, memory_info& mem) -void MemInfoManager::ParseEntry (TiXmlElement* entry, memory_info& mem, map & knownEntries) +void MemInfoManager::ParseEntry (TiXmlElement* entry, memory_info* mem, map & knownEntries) { TiXmlElement* pMemEntry; const char *cstr_version = entry->Attribute("version"); const char *cstr_os = entry->Attribute("os"); const char *cstr_base = entry->Attribute("base"); const char *cstr_rebase = entry->Attribute("rebase"); -// printf("%s : %s\n",cstr_version, cstr_os); if(cstr_base) { string base = cstr_base; @@ -95,28 +94,28 @@ void MemInfoManager::ParseEntry (TiXmlElement* entry, memory_info& mem, map setVersion(cstr_version); + mem->setOS(cstr_os); // offset inherited addresses by 'rebase'. int32_t rebase = 0; if(cstr_rebase) { - rebase = mem.getBase() + strtol(cstr_rebase, NULL, 16); - mem.RebaseAddresses(rebase); + rebase = mem->getBase() + strtol(cstr_rebase, NULL, 16); + mem->RebaseAddresses(rebase); } //set base to default, we're overwriting this because the previous rebase could cause havoc on Vista/7 if(os == "windows") { // set default image base. this is fixed for base relocation later - mem.setBase(0x400000); + mem->setBase(0x400000); } else if(os == "linux") { // this is wrong... I'm not going to do base image relocation on linux though. // users are free to use a sane kernel that doesn't do this kind of **** by default - mem.setBase(0x0); + mem->setBase(0x0); } else if ( os == "all") { @@ -154,39 +153,39 @@ void MemInfoManager::ParseEntry (TiXmlElement* entry, memory_info& mem, map setHexValue(name, value); } else if (type == "Address") { - mem.setAddress(name, value); + mem->setAddress(name, value); } else if (type == "Offset") { - mem.setOffset(name, value); + mem->setOffset(name, value); } else if (type == "String") { - mem.setString(name, value); + mem->setString(name, value); } else if (type == "Profession") { - mem.setProfession(value,name); + mem->setProfession(value,name); } else if (type == "Job") { - mem.setJob(value,name); + mem->setJob(value,name); } else if (type == "Skill") { - mem.setSkill(value,name); + mem->setSkill(value,name); } else if (type == "Trait") { - mem.setTrait(value, name,pMemEntry->Attribute("level_0"),pMemEntry->Attribute("level_1"),pMemEntry->Attribute("level_2"),pMemEntry->Attribute("level_3"),pMemEntry->Attribute("level_4"),pMemEntry->Attribute("level_5")); + mem->setTrait(value, name,pMemEntry->Attribute("level_0"),pMemEntry->Attribute("level_1"),pMemEntry->Attribute("level_2"),pMemEntry->Attribute("level_3"),pMemEntry->Attribute("level_4"),pMemEntry->Attribute("level_5")); } else if (type == "Labor") { - mem.setLabor(value,name); + mem->setLabor(value,name); } else { @@ -235,6 +234,10 @@ bool MemInfoManager::loadFile(string path_to_xml) // transform elements { // trash existing list + for(int i = 0; i < meminfo.size(); i++) + { + delete meminfo[i]; + } meminfo.clear(); TiXmlElement* pMemInfo=hRoot.FirstChild( "MemoryDescriptors" ).FirstChild( "Entry" ).Element(); map map_pNamedEntries; @@ -251,7 +254,7 @@ bool MemInfoManager::loadFile(string path_to_xml) } for(uint32_t i = 0; i< v_pEntries.size();i++) { - memory_info mem; + memory_info *mem = new memory_info(); //FIXME: add a set of entries processed in a step of this cycle, use it to check for infinite loops /* recursive */ParseEntry( v_pEntries[i] , mem , map_pNamedEntries); meminfo.push_back(mem); diff --git a/library/DFMemInfoManager.h b/library/DFMemInfoManager.h index d4e7812d8..be89c57b9 100644 --- a/library/DFMemInfoManager.h +++ b/library/DFMemInfoManager.h @@ -38,9 +38,9 @@ namespace DFHack bool loadFile( string path_to_xml); bool isInErrorState() const {return error;}; private: - std::vector meminfo; - void ParseVTable(TiXmlElement* vtable, memory_info& mem); - void ParseEntry (TiXmlElement* entry, memory_info& mem, map & knownEntries); + std::vector meminfo; + void ParseVTable(TiXmlElement* vtable, memory_info* mem); + void ParseEntry (TiXmlElement* entry, memory_info* mem, map & knownEntries); bool error; }; } diff --git a/library/DFProcess-linux-SHM.cpp b/library/DFProcess-linux-SHM.cpp index 5821e129c..db988037b 100644 --- a/library/DFProcess-linux-SHM.cpp +++ b/library/DFProcess-linux-SHM.cpp @@ -60,7 +60,7 @@ class SHMProcess::Private bool suspended; bool identified; - bool validate(char * exe_file, uint32_t pid, vector & known_versions); + bool validate(char* exe_file, uint32_t pid, std::vector< memory_info* >& known_versions); bool waitWhile (DF_PINGPONG state); bool DF_TestBridgeVersion(bool & ret); bool DF_GetPID(pid_t & ret); @@ -124,7 +124,7 @@ bool SHMProcess::Private::DF_GetPID(pid_t & ret) return true; } -SHMProcess::SHMProcess(vector & known_versions) +SHMProcess::SHMProcess(vector & known_versions) : d(new Private()) { char exe_link_name [256]; @@ -214,19 +214,19 @@ bool SHMProcess::isIdentified() return d->identified; } -bool SHMProcess::Private::validate(char * exe_file, uint32_t pid, vector & known_versions) +bool SHMProcess::Private::validate(char * exe_file, uint32_t pid, vector & known_versions) { md5wrapper md5; // get hash of the running DF process string hash = md5.getHashFromFile(exe_file); - vector::iterator it; + vector::iterator it; cerr << exe_file << " " << hash << endl; // iterate over the list of memory locations for ( it=known_versions.begin() ; it < known_versions.end(); it++ ) { - if(hash == (*it).getString("md5")) // are the md5 hashes the same? + if(hash == (*it)->getString("md5")) // are the md5 hashes the same? { - memory_info * m = &*it; + memory_info * m = *it; my_descriptor = m; my_pid = pid; identified = true; diff --git a/library/DFProcess-linux-wine.cpp b/library/DFProcess-linux-wine.cpp index f4b6d670e..6605b92dd 100644 --- a/library/DFProcess-linux-wine.cpp +++ b/library/DFProcess-linux-wine.cpp @@ -49,10 +49,10 @@ class WineProcess::Private bool attached; bool suspended; bool identified; - bool validate(char * exe_file, uint32_t pid, char * mem_file, vector & known_versions); + bool validate(char * exe_file, uint32_t pid, char * mem_file, vector & known_versions); }; -WineProcess::WineProcess(uint32_t pid, vector & known_versions) +WineProcess::WineProcess(uint32_t pid, vector & known_versions) : d(new Private()) { char dir_name [256]; @@ -129,20 +129,20 @@ bool WineProcess::isIdentified() return d->identified; } -bool WineProcess::Private::validate(char * exe_file,uint32_t pid, char * memFile, vector & known_versions) +bool WineProcess::Private::validate(char* exe_file, uint32_t pid, char* mem_file, std::vector< memory_info* >& known_versions) { md5wrapper md5; // get hash of the running DF process string hash = md5.getHashFromFile(exe_file); - vector::iterator it; + vector::iterator it; // iterate over the list of memory locations for ( it=known_versions.begin() ; it < known_versions.end(); it++ ) { // are the md5 hashes the same? - if(memory_info::OS_WINDOWS == (*it).getOS() && hash == (*it).getString("md5")) + if(memory_info::OS_WINDOWS == (*it)->getOS() && hash == (*it)->getString("md5")) { - memory_info * m = &*it; + memory_info * m = *it; my_descriptor = m; my_handle = my_pid = pid; // tell WineProcess about the /proc/PID/mem file diff --git a/library/DFProcess-linux.cpp b/library/DFProcess-linux.cpp index 7801520ba..771c2d82d 100644 --- a/library/DFProcess-linux.cpp +++ b/library/DFProcess-linux.cpp @@ -49,10 +49,10 @@ class NormalProcess::Private bool attached; bool suspended; bool identified; - bool validate(char * exe_file, uint32_t pid, char * mem_file, vector & known_versions); + bool validate(char * exe_file, uint32_t pid, char * mem_file, vector & known_versions); }; -NormalProcess::NormalProcess(uint32_t pid, vector & known_versions) +NormalProcess::NormalProcess(uint32_t pid, vector< memory_info* >& known_versions) : d(new Private()) { char dir_name [256]; @@ -104,20 +104,20 @@ bool NormalProcess::isIdentified() return d->identified; } -bool NormalProcess::Private::validate(char * exe_file,uint32_t pid, char * memFile, vector & known_versions) +bool NormalProcess::Private::validate(char * exe_file,uint32_t pid, char * memFile, vector & known_versions) { md5wrapper md5; // get hash of the running DF process string hash = md5.getHashFromFile(exe_file); - vector::iterator it; + vector::iterator it; // iterate over the list of memory locations for ( it=known_versions.begin() ; it < known_versions.end(); it++ ) { - if(hash == (*it).getString("md5")) // are the md5 hashes the same? + if(hash == (*it)->getString("md5")) // are the md5 hashes the same? { - memory_info * m = &*it; - if (memory_info::OS_LINUX == (*it).getOS()) + memory_info * m = *it; + if (memory_info::OS_LINUX == m->getOS()) { my_descriptor = m; my_handle = my_pid = pid; diff --git a/library/DFProcess-windows-SHM.cpp b/library/DFProcess-windows-SHM.cpp index 7210f8aee..5606189ef 100644 --- a/library/DFProcess-windows-SHM.cpp +++ b/library/DFProcess-windows-SHM.cpp @@ -145,7 +145,7 @@ bool SHMProcess::Private::DF_GetPID(uint32_t & ret) return true; } -SHMProcess::SHMProcess(vector & known_versions) +SHMProcess::SHMProcess(vector & known_versions) : d(new Private()) { // get server and client mutex @@ -227,13 +227,13 @@ SHMProcess::SHMProcess(vector & known_versions) read(base + pe_offset+ sizeof(pe_header), sizeof(sections) , (uint8_t *)§ions ); // iterate over the list of memory locations - vector::iterator it; + vector::iterator it; for ( it=known_versions.begin() ; it < known_versions.end(); it++ ) { - uint32_t pe_timestamp = (*it).getHexValue("pe_timestamp"); + uint32_t pe_timestamp = (*it)->getHexValue("pe_timestamp"); if (pe_timestamp == pe_header.FileHeader.TimeDateStamp) { - memory_info *m = new memory_info(*it); + memory_info *m = new memory_info(**it); m->RebaseAll(base); d->my_descriptor = m; d->identified = true; diff --git a/library/DFProcess-windows.cpp b/library/DFProcess-windows.cpp index 21b4a5b67..b2f684a07 100644 --- a/library/DFProcess-windows.cpp +++ b/library/DFProcess-windows.cpp @@ -49,7 +49,7 @@ class NormalProcess::Private bool identified; }; -NormalProcess::NormalProcess(uint32_t pid, vector & known_versions) +NormalProcess::NormalProcess(uint32_t pid, vector & known_versions) : d(new Private()) { HMODULE hmod = NULL; @@ -85,24 +85,24 @@ NormalProcess::NormalProcess(uint32_t pid, vector & known_versions d->my_handle = 0; // see if there's a version entry that matches this process - vector::iterator it; + vector::iterator it; for ( it=known_versions.begin() ; it < known_versions.end(); it++ ) { // filter by OS - if(memory_info::OS_WINDOWS != (*it).getOS()) + if(memory_info::OS_WINDOWS != (*it)->getOS()) continue; // filter by timestamp - uint32_t pe_timestamp = (*it).getHexValue("pe_timestamp"); + uint32_t pe_timestamp = (*it)->getHexValue("pe_timestamp"); if (pe_timestamp != pe_header.FileHeader.TimeDateStamp) continue; // all went well { - printf("Match found! Using version %s.\n", (*it).getVersion().c_str()); + printf("Match found! Using version %s.\n", (*it)->getVersion().c_str()); d->identified = true; // give the process a data model and memory layout fixed for the base of first module - memory_info *m = new memory_info(*it); + memory_info *m = new memory_info(**it); m->RebaseAll(base); // keep track of created memory_info object so we can destroy it later d->my_descriptor = m; diff --git a/library/DFProcess.h b/library/DFProcess.h index 194ac5715..13d32c7af 100644 --- a/library/DFProcess.h +++ b/library/DFProcess.h @@ -129,7 +129,7 @@ namespace DFHack Private * const d; public: - NormalProcess(uint32_t pid, vector & known_versions); + NormalProcess(uint32_t pid, vector & known_versions); ~NormalProcess(); bool attach(); bool detach(); @@ -181,7 +181,7 @@ namespace DFHack Private * const d; public: - SHMProcess(vector & known_versions); + SHMProcess(vector & known_versions); ~SHMProcess(); // Set up stuff so we can read memory bool attach(); @@ -235,7 +235,7 @@ namespace DFHack Private * const d; public: - WineProcess(uint32_t pid, vector & known_versions); + WineProcess(uint32_t pid, vector & known_versions); ~WineProcess(); bool attach(); bool detach(); diff --git a/library/DFProcessEnumerator-linux.cpp b/library/DFProcessEnumerator-linux.cpp index 321d151f0..f4d02e2a1 100644 --- a/library/DFProcessEnumerator-linux.cpp +++ b/library/DFProcessEnumerator-linux.cpp @@ -46,9 +46,6 @@ bool ProcessEnumerator::findProcessess() { DIR *dir_p; struct dirent *dir_entry_p; - - int errorcount; - int result; Process *p = 0; p = new SHMProcess(d->meminfo->meminfo);