diff --git a/library/Core.cpp b/library/Core.cpp index e18b03140..52705af1a 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -1532,10 +1532,7 @@ Core::Core() : { // init the console. This must be always the first step! plug_mgr = 0; - vif = 0; - p = 0; errorstate = false; - vinfo = 0; started = false; memset(&(s_mods), 0, sizeof(s_mods)); @@ -1614,24 +1611,24 @@ bool Core::Init() #else const char * path = "hack\\symbols.xml"; #endif - vif = new DFHack::VersionInfoFactory(); + auto local_vif = dts::make_unique(); cerr << "Identifying DF version.\n"; try { - vif->loadFile(path); + local_vif->loadFile(path); } catch(Error::All & err) { std::stringstream out; out << "Error while reading symbols.xml:\n"; out << err.what() << std::endl; - delete vif; - vif = NULL; errorstate = true; fatal(out.str()); return false; } - std::unique_ptr local_p(new DFHack::Process(vif)); + vif = std::move(local_vif); + auto local_p = dts::make_unique(*vif); + local_p->ValidateDescriptionOS(); vinfo = local_p->getDescriptor(); if(!vinfo || !local_p->isIdentified()) @@ -1670,18 +1667,6 @@ bool Core::Init() cerr << "Version: " << vinfo->getVersion() << endl; p = std::move(local_p); -#if defined(_WIN32) - const OSType expected = OS_WINDOWS; -#elif defined(_DARWIN) - const OSType expected = OS_APPLE; -#else - const OSType expected = OS_LINUX; -#endif - if (expected != vinfo->getOS()) { - cerr << "OS mismatch; resetting to " << int(expected) << endl; - vinfo->setOS(expected); - } - // Init global object pointers df::global::InitGlobals(); diff --git a/library/DataStatics.cpp b/library/DataStatics.cpp index 1e4b21be9..31c8c0200 100644 --- a/library/DataStatics.cpp +++ b/library/DataStatics.cpp @@ -17,7 +17,7 @@ namespace { } #define INIT_GLOBAL_FUNCTION_PREFIX \ - DFHack::VersionInfo *global_table_ = DFHack::Core::getInstance().vinfo; \ + DFHack::VersionInfo *global_table_ = DFHack::Core::getInstance().vinfo.get(); \ void * tmp_; #define INIT_GLOBAL_FUNCTION_ITEM(type,name) \ diff --git a/library/Process-darwin.cpp b/library/Process-darwin.cpp index 13657ca17..4e1abc108 100644 --- a/library/Process-darwin.cpp +++ b/library/Process-darwin.cpp @@ -42,14 +42,13 @@ using namespace std; #include #include "MemAccess.h" #include "Memory.h" -#include "MiscUtils.h" #include "VersionInfoFactory.h" #include "VersionInfo.h" #include "Error.h" #include using namespace DFHack; -Process::Process(VersionInfoFactory * known_versions) : identified(false), my_pe(0) +Process::Process(const VersionInfoFactory& known_versions) : identified(false), my_pe(0) { int target_result; @@ -67,10 +66,10 @@ Process::Process(VersionInfoFactory * known_versions) : identified(false), my_pe // get hash of the running DF process my_md5 = md5.getHashFromFile(real_path, length, (char *) first_kb); // create linux process, add it to the vector - const VersionInfo * vinfo = known_versions->getVersionInfoByMD5(my_md5); + auto vinfo = known_versions.getVersionInfoByMD5(my_md5); if(vinfo) { - my_descriptor = dts::make_unique(*vinfo); + my_descriptor = std::make_shared(*vinfo); identified = true; } else diff --git a/library/Process-linux.cpp b/library/Process-linux.cpp index c5dea6b46..a7f09a7f6 100644 --- a/library/Process-linux.cpp +++ b/library/Process-linux.cpp @@ -40,14 +40,13 @@ using namespace std; #include #include "MemAccess.h" #include "Memory.h" -#include "MiscUtils.h" #include "VersionInfoFactory.h" #include "VersionInfo.h" #include "Error.h" #include using namespace DFHack; -Process::Process(VersionInfoFactory * known_versions) : identified(false), my_pe(0) +Process::Process(const VersionInfoFactory& known_versions) : identified(false), my_pe(0) { const char * dir_name = "/proc/self/"; const char * exe_link_name = "/proc/self/exe"; @@ -71,10 +70,10 @@ Process::Process(VersionInfoFactory * known_versions) : identified(false), my_pe // get hash of the running DF process my_md5 = md5.getHashFromFile(self_exe_name, length, (char *) first_kb); // create linux process, add it to the vector - const VersionInfo * vinfo = known_versions->getVersionInfoByMD5(my_md5); + auto vinfo = known_versions.getVersionInfoByMD5(my_md5); if(vinfo) { - my_descriptor = dts::make_unique(*vinfo); + my_descriptor = std::make_shared(*vinfo); identified = true; } else diff --git a/library/Process-windows.cpp b/library/Process-windows.cpp index eee7c4feb..9e3b7d1fb 100644 --- a/library/Process-windows.cpp +++ b/library/Process-windows.cpp @@ -44,7 +44,6 @@ using namespace std; #include "Error.h" #include "MemAccess.h" #include "Memory.h" -#include "MiscUtils.h" using namespace DFHack; namespace DFHack { @@ -63,7 +62,7 @@ namespace DFHack char * base; }; } -Process::Process(VersionInfoFactory * factory) : identified(false) +Process::Process(const VersionInfoFactory& factory) : identified(false) { HMODULE hmod = NULL; DWORD needed; @@ -96,12 +95,12 @@ Process::Process(VersionInfoFactory * factory) : identified(false) return; } my_pe = d->pe_header.FileHeader.TimeDateStamp; - const VersionInfo* vinfo = factory->getVersionInfoByPETimestamp(my_pe); + auto vinfo = factory.getVersionInfoByPETimestamp(my_pe); if(vinfo) { identified = true; // give the process a data model and memory layout fixed for the base of first module - my_descriptor = dts::make_unique(*vinfo); + my_descriptor = std::make_shared(*vinfo); my_descriptor->rebaseTo(getBase()); } else diff --git a/library/VersionInfoFactory.cpp b/library/VersionInfoFactory.cpp index 7a15a2d81..4202df5bb 100644 --- a/library/VersionInfoFactory.cpp +++ b/library/VersionInfoFactory.cpp @@ -56,24 +56,24 @@ void VersionInfoFactory::clear() error = false; } -const VersionInfo * VersionInfoFactory::getVersionInfoByMD5(string hash) +std::shared_ptr VersionInfoFactory::getVersionInfoByMD5(string hash) const { - for(size_t i = 0; i < versions.size();i++) + for (const auto& version : versions) { - if(versions[i]->hasMD5(hash)) - return versions[i].get(); + if(version->hasMD5(hash)) + return version; } - return 0; + return nullptr; } -const VersionInfo * VersionInfoFactory::getVersionInfoByPETimestamp(uintptr_t timestamp) +std::shared_ptr VersionInfoFactory::getVersionInfoByPETimestamp(uintptr_t timestamp) const { - for(size_t i = 0; i < versions.size();i++) + for (const auto& version : versions) { - if(versions[i]->hasPE(timestamp)) - return versions[i].get(); + if(version->hasPE(timestamp)) + return version; } - return 0; + return nullptr; } void VersionInfoFactory::ParseVersion (TiXmlElement* entry, VersionInfo* mem) diff --git a/library/include/Core.h b/library/include/Core.h index d83ee9aea..8e70f928f 100644 --- a/library/include/Core.h +++ b/library/include/Core.h @@ -192,7 +192,7 @@ namespace DFHack DFHack::Console &getConsole() { return con; } std::unique_ptr p; - DFHack::VersionInfo * vinfo; + std::shared_ptr vinfo; DFHack::Windows::df_window * screen_window; static void print(const char *format, ...) Wformat(printf,1,2); @@ -235,7 +235,7 @@ namespace DFHack struct Cond; // FIXME: shouldn't be kept around like this - DFHack::VersionInfoFactory * vif; + std::unique_ptr vif; // Module storage struct { diff --git a/library/include/MemAccess.h b/library/include/MemAccess.h index da94e81df..7f3be74df 100644 --- a/library/include/MemAccess.h +++ b/library/include/MemAccess.h @@ -35,9 +35,10 @@ distribution. #include #include +#include "VersionInfo.h" + namespace DFHack { - struct VersionInfo; class Process; //class Window; class DFVector; @@ -79,7 +80,7 @@ namespace DFHack { public: /// this is the single most important destructor ever. ~px - Process(VersionInfoFactory * known_versions); + Process(const VersionInfoFactory& known_versions); ~Process(); /// read a 8-byte integer uint64_t readQuad(const void * address) @@ -247,10 +248,15 @@ namespace DFHack void getMemRanges(std::vector & ranges ); /// get the symbol table extension of this process - VersionInfo *getDescriptor() + std::shared_ptr getDescriptor() { - return my_descriptor.get(); + return my_descriptor; + }; + + void ValidateDescriptionOS() { + my_descriptor->ValidateOS(); }; + uintptr_t getBase(); /// get the DF Process ID int getPID(); @@ -292,7 +298,7 @@ namespace DFHack std::string getMD5() { return my_md5; } private: - std::unique_ptr my_descriptor; + std::shared_ptr my_descriptor; PlatformSpecific *d; bool identified; uint32_t my_pid; diff --git a/library/include/VersionInfo.h b/library/include/VersionInfo.h index dc959f1db..0d069c00c 100644 --- a/library/include/VersionInfo.h +++ b/library/include/VersionInfo.h @@ -26,6 +26,7 @@ distribution. #pragma once #include +#include #include #include #include @@ -169,5 +170,19 @@ namespace DFHack { return OS; }; + + void ValidateOS() { +#if defined(_WIN32) + const OSType expected = OS_WINDOWS; +#elif defined(_DARWIN) + const OSType expected = OS_APPLE; +#else + const OSType expected = OS_LINUX; +#endif + if (expected != getOS()) { + std::cerr << "OS mismatch; resetting to " << int(expected) << std::endl; + setOS(expected); + } + } }; } diff --git a/library/include/VersionInfoFactory.h b/library/include/VersionInfoFactory.h index a03c11aa1..a6b1a17d5 100644 --- a/library/include/VersionInfoFactory.h +++ b/library/include/VersionInfoFactory.h @@ -41,12 +41,12 @@ namespace DFHack ~VersionInfoFactory(); bool loadFile( std::string path_to_xml); bool isInErrorState() const {return error;}; - const VersionInfo * getVersionInfoByMD5(std::string md5string); - const VersionInfo * getVersionInfoByPETimestamp(uintptr_t timestamp); - std::vector> versions; + std::shared_ptr getVersionInfoByMD5(std::string md5string) const; + std::shared_ptr getVersionInfoByPETimestamp(uintptr_t timestamp) const; // trash existing list void clear(); private: + std::vector> versions; void ParseVersion (TiXmlElement* version, VersionInfo* mem); bool error; };