Lots of comments. Using templates in the search tool.

develop
Petr Mrázek 2010-05-30 05:13:59 +02:00
parent 5ee4acfd2e
commit 123fb5a9d0
11 changed files with 446 additions and 202 deletions

@ -23,10 +23,10 @@ distribution.
*/
#include "Internal.h"
#include "DFMemInfoManager.h"
#include "dfhack/DFProcess.h"
#include "dfhack/DFProcessEnumerator.h"
#include "dfhack/DFMemInfoManager.h"
#include "dfhack/DFError.h"
#include "dfhack/DFContext.h"

@ -23,8 +23,9 @@ distribution.
*/
#include "Internal.h"
#include "DFMemInfoManager.h"
#include "dfhack/DFMemInfo.h"
#include "dfhack/DFMemInfoManager.h"
#include "dfhack/DFError.h"
using namespace DFHack;

@ -23,10 +23,12 @@ distribution.
*/
#include "Internal.h"
#include "DFMemInfoManager.h"
#include "dfhack/DFProcessEnumerator.h"
#include "dfhack/DFProcess.h"
#include "dfhack/DFMemInfo.h"
#include "dfhack/DFMemInfoManager.h"
using namespace DFHack;
@ -223,7 +225,7 @@ uint64_t FileTime_to_POSIX(FILETIME ft)
void ProcessEnumerator::Private::EnumPIDs (vector <ProcessID> &PIDs)
{
FILETIME ftCreate, ftExit, ftKernel, ftUser;
PIDs.clear(); // make sure the vector is clear
// Get the list of process identifiers.
@ -254,7 +256,7 @@ void ProcessEnumerator::Private::EnumPIDs (vector <ProcessID> &PIDs)
}
#endif
bool ProcessEnumerator::Refresh( BadProcesses* invalidated_processes)
bool ProcessEnumerator::Refresh( BadProcesses* invalidated_processes )
{
// PIDs to process
vector <ProcessID> PIDs;
@ -330,11 +332,6 @@ bool ProcessEnumerator::Refresh( BadProcesses* invalidated_processes)
return false;
}
bool ProcessEnumerator::findProcessess()
{
return Refresh();
}
uint32_t ProcessEnumerator::size()
{
return d->Processes.size();

@ -44,74 +44,78 @@ namespace DFHack
class DFContextShared;
class WindowIO;
class Process;
class DFHACK_EXPORT Context
{
public:
Context(Process * p);
~Context();
bool isValid();
bool Attach();
bool Detach();
bool isAttached();
/// stop the tracked process
bool Suspend();
/// @return true if the process is stopped
bool isSuspended();
/// stop the tracked process, asynchronous
bool AsyncSuspend();
/// resume the tracked process
bool Resume();
/// forces resume on Windows. This can be a bad thing with multiple tools running!
bool ForceResume();
memory_info *getMemoryInfo();
Process* getProcess();
void ReadRaw (const uint32_t offset, const uint32_t size, uint8_t *target);
void WriteRaw (const uint32_t offset, const uint32_t size, uint8_t *source);
// FIXME: this is crap.
// get the creatures module
/// get the creatures module
Creatures * getCreatures();
// get the maps module
/// get the maps module
Maps * getMaps();
// get the gui module
/// get the gui module
Gui * getGui();
// get the world module
/// get the world module
World * getWorld();
// get the position module
/// get the position module
Position * getPosition();
// get the materials module
/// get the materials module
Materials * getMaterials();
// get the items module
/// get the items module
Items * getItems();
// get the translation module
/// get the translation module
Translation * getTranslation();
// get the vegetation module
/// get the vegetation module
Vegetation * getVegetation();
// get the buildings module
/// get the buildings module
Buildings * getBuildings();
// get the constructions module
/// get the constructions module
Constructions * getConstructions();
// get the Window management and I/O module
/// get the Window management and I/O module
WindowIO * getWindow();
// DEAD CODE, WAITING TO BE UPDATED TO DF2010
/*
* Effects like mist, dragonfire or dust
*/

@ -74,7 +74,7 @@ namespace DFHack
/**
* Get a context by index
* @param index index of the context to be returned
* @return pointer to a Context
* @return pointer to a Context. 0 if the index is out of range.
*/
Context * operator[](uint32_t index);
@ -106,37 +106,37 @@ namespace DFHack
public:
BadContexts();
/**
* Destructor.
* All Processes and Contexts tracked by the BadContexts object will be destroyed also.
*/
* Destructor.
* All Processes and Contexts tracked by the BadContexts object will be destroyed also.
*/
~BadContexts();
/**
* Test if a Context is among the invalidated Contexts
* @param c pointer to a Context to be checked
* @return true if the Context is among the invalidated. false otherwise.
*/
* Test if a Context is among the invalidated Contexts
* @param c pointer to a Context to be checked
* @return true if the Context is among the invalidated. false otherwise.
*/
bool Contains(Context* c);
/**
* Test if a Process is among the invalidated Processes/Contexts
* @param p pointer to a Process to be checked
* @see DFHack::Process
* @return true if the Process is among the invalidated. false otherwise.
*/
* Test if a Process is among the invalidated Processes/Contexts
* @param p pointer to a Process to be checked
* @see DFHack::Process
* @return true if the Process is among the invalidated. false otherwise.
*/
bool Contains(Process* p);
/**
* Get the number of tracked invalid contexts.
* @return Number of tracked invalid contexts
*/
* Get the number of tracked invalid contexts.
* @return Number of tracked invalid contexts
*/
uint32_t size();
/**
* Get an invalid Context by index
* @param index index of the invalid Context to be returned
* @return pointer to an invalid Context
*/
* Get an invalid Context by index
* @param index index of the invalid Context to be returned
* @return pointer to an invalid Context
*/
Context * operator[](uint32_t index);
};
} // namespace DFHack

@ -85,7 +85,7 @@ namespace DFHack
uint32_t type_offset; // offset of type data for multiclass
vector<t_type *> subs;
};
class DFHACK_EXPORT memory_info
{
private:
@ -114,7 +114,7 @@ namespace DFHack
int32_t getOffset (const char *);
uint32_t getAddress (const char *);
uint32_t getHexValue (const char *);
std::string getString (const std::string&);
std::string getProfession(const uint32_t) const;
std::string getJob(const uint32_t) const;
@ -154,34 +154,34 @@ namespace DFHack
void RebaseVTable(const int32_t offset);
void setParentProcess(Process * _p);
t_class * setClass (const char * classname, uint32_t vptr = 0, uint32_t typeoffset = 0);
void setClassChild (t_class * parent, const char * classname, const char * type);
/*
/**
* Get a classID from an address. The address has to point to the start of a virtual object (one with a virtual base class)
* uses memory reading directly, needs suspend. input = address of the object
* fails if it's unable to read from memory
*/
bool resolveObjectToClassID (const uint32_t address, int32_t & classID);
/*
/**
* Get a ClassID when you know the classname. can fail if the class is not in the cache
*/
bool resolveClassnameToClassID (const std::string classname, int32_t & classID);
/*
/**
* Get a vptr from a classname. Can fail if the type is not in the cache
* limited to normal classes, variable-dependent types will resolve to the base class
*/
bool resolveClassnameToVPtr ( const std::string classname, uint32_t & vptr );
/*
/**
* Get a classname from a previous classID. Can fail if the type is not in the cache (you use bogus classID)
*/
bool resolveClassIDToClassname (const int32_t classID, std::string & classname);
/*
/**
* Get the internal classID->classname mapping (for speed). DO NOT MANIPULATE THE VECTOR!
*/
const vector<std::string> * getClassIDMapping();

@ -72,92 +72,115 @@ namespace DFHack
if (address >= start && address <= end) return true;
return false;
}
inline void print()
{
std::cout << std::hex << start << " - " << end << "|" << (read ? "r" : "-") << (write ? "w" : "-") << (execute ? "x" : "-") << "|" << name << std::endl;
}
uint8_t * buffer;
};
class DFHACK_EXPORT Process
{
public:
// this is the single most important destructor ever. ~px
/// this is the single most important destructor ever. ~px
virtual ~Process(){};
// Set up stuff so we can read memory, suspends synchronously
/// Set up stuff so we can read memory, suspends synchronously
virtual bool attach() = 0;
// detach from DF, resume its execution if it's suspended
/// detach from DF, resume its execution if it's suspended
virtual bool detach() = 0;
// synchronous suspend
// waits for DF to be actually suspended,
// this might take a while depending on implementation
/**
* synchronous suspend
* waits for DF to be actually suspended,
* this might take a while depending on implementation
*/
virtual bool suspend() = 0;
// asynchronous suspend to use together with polling and timers
/// asynchronous suspend to use together with polling and timers
virtual bool asyncSuspend() = 0;
// resume DF execution
/// resume DF execution
virtual bool resume() = 0;
// force-resume DF execution
/// force-resume DF execution
virtual bool forceresume() = 0;
/// read a 8-byte integer
virtual uint64_t readQuad(const uint32_t address) = 0;
/// read a 8-byte integer
virtual void readQuad(const uint32_t address, uint64_t & value) = 0;
/// write a 8-byte integer
virtual void writeQuad(const uint32_t address, const uint64_t value) = 0;
/// read a 4-byte integer
virtual uint32_t readDWord(const uint32_t address) = 0;
/// read a 4-byte integer
virtual void readDWord(const uint32_t address, uint32_t & value) = 0;
/// write a 4-byte integer
virtual void writeDWord(const uint32_t address, const uint32_t value) = 0;
/// read a float
virtual float readFloat(const uint32_t address) = 0;
/// write a float
virtual void readFloat(const uint32_t address, float & value) = 0;
/// read a 2-byte integer
virtual uint16_t readWord(const uint32_t address) = 0;
/// read a 2-byte integer
virtual void readWord(const uint32_t address, uint16_t & value) = 0;
/// write a 2-byte integer
virtual void writeWord(const uint32_t address, const uint16_t value) = 0;
/// read a byte
virtual uint8_t readByte(const uint32_t address) = 0;
/// read a byte
virtual void readByte(const uint32_t address, uint8_t & value) = 0;
/// write a byte
virtual void writeByte(const uint32_t address, const uint8_t value) = 0;
/// read an arbitrary amount of bytes
virtual void read( uint32_t address, uint32_t length, uint8_t* buffer) = 0;
/// write an arbitrary amount of bytes
virtual void write(uint32_t address, uint32_t length, uint8_t* buffer) = 0;
// read a string
/// read an STL string
virtual const string readSTLString (uint32_t offset) = 0;
/// read an STL string
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;
// get class name of an object with rtti/type info
/// get class name of an object with rtti/type info
virtual string readClassName(uint32_t vptr) = 0;
/// read a null-terminated C string
virtual const std::string readCString (uint32_t offset) = 0;
/// @return true if the process is suspended
virtual bool isSuspended() = 0;
/// @return true if the process is attached
virtual bool isAttached() = 0;
/// @return true if the process is identified -- has a Memory.xml entry
virtual bool isIdentified() = 0;
// find the thread IDs of the process
/// find the thread IDs of the process
virtual bool getThreadIDs(vector<uint32_t> & threads ) = 0;
// get virtual memory ranges of the process (what is mapped where)
/// get virtual memory ranges of the process (what is mapped where)
virtual void getMemRanges( vector<t_memrange> & ranges ) = 0;
// get the flattened Memory.xml entry of this process
/// get the flattened Memory.xml entry of this process
virtual memory_info *getDescriptor() = 0;
// get the DF Process ID
/// get the DF Process ID
virtual int getPID() = 0;
// get module index by name and version. bool 1 = error
/// get module index by name and version. bool 1 = error
virtual bool getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT) = 0;
// get the SHM start if available
/// get the SHM start if available
virtual char * getSHMStart (void) = 0;
// set a SHM command and wait for a response, return 0 on error or throw exception
/// set a SHM command and wait for a response, return 0 on error or throw exception
virtual bool SetAndWait (uint32_t state) = 0;
};
////////////////////////////////////////////////////////////////////////////
// Compiler appeasement area. Not worth a look really... //
////////////////////////////////////////////////////////////////////////////
class DFHACK_EXPORT NormalProcess : virtual public Process
{
friend class ProcessEnumerator;
class Private;
private:
Private * const d;
public:
NormalProcess(uint32_t pid, vector <memory_info *> & known_versions);
~NormalProcess();

@ -33,35 +33,99 @@ namespace DFHack
class memory_info;
class Process;
class BadProcesses;
/*
* Process manager
/**
* Process enumerator
* Used to enumerate, create and destroy Processes.
* @see DFHack::Process
*/
class DFHACK_EXPORT ProcessEnumerator
{
class Private;
Private * const d;
public:
/**
* Constructs the ProcessEnumerator.
* @param path_to_xml the path to the file that defines memory offsets. (Memory.xml)
*/
ProcessEnumerator( string path_to_xml );
/**
* Destroys the ProcessEnumerator.
*/
~ProcessEnumerator();
/**
* Refresh the internal list of valid Process objects.
* @param invalidated_processes pointer to a BadProcesses object. Not required. All processes are automatically destroyed if the object is not provided.
* @see DFHack::BadProcesses
* @return true if there's at least one valit Process
*/
bool Refresh(BadProcesses * invalidated_processes = 0);
bool findProcessess();
/**
* @return Number of tracked processes
*/
uint32_t size();
/**
* Get a Process by index
* @param index index of the Process to be returned
* @return pointer to a Process. 0 if the index is out of range.
*/
Process * operator[](uint32_t index);
/**
* Destroy all tracked Process objects
* Normally called during object destruction. Calling this from outside ProcessManager is nasty.
*/
void purge(void);
};
/**
* Class used for holding a set of invalidated Process objects temporarily and destroy them safely.
* @see DFHack::Process
*/
class DFHACK_EXPORT BadProcesses
{
class Private;
Private * const d;
void push_back(Process * p);
friend class ProcessEnumerator;
void clear();
public:
BadProcesses();
/**
* Destructor.
* All Processes tracked by the BadProcesses object will be destroyed also.
*/
~BadProcesses();
/**
* Test if a Process is among the invalidated Processes
* @param p pointer to a Process to be checked
* @return true if the Process is among the invalidated. false otherwise.
*/
bool Contains(Process* p);
/**
* Remove a Process from the tracked invalidated Processes. Used by BadContexts.
* @param p pointer to a Process to be excised
* @see DFHack::BadContexts
* @return true if the Process was among the invalidated. false otherwise.
*/
bool excise (Process* p);
/**
* Get the number of tracked invalid contexts.
* @return Number of tracked invalid contexts
*/
uint32_t size();
void clear();
/**
* Get an invalid Process by index
* @param index index of the invalid Process to be returned
* @return pointer to an invalid Process
*/
Process * operator[](uint32_t index);
};
}

@ -11,7 +11,7 @@ namespace DFHack
/***************************************************************************
T Y P E S
***************************************************************************/
enum e_feature
{
feature_Other,
@ -19,6 +19,7 @@ namespace DFHack
feature_Underworld,
feature_Hell_Temple
};
static const char * sa_feature[]=
{
(char*)"Other",
@ -26,6 +27,8 @@ namespace DFHack
(char*)"Underworld",
(char*)"Hell Temple"
};
/// used as a key for the local feature map. combines X an Y coords.
union planecoord
{
uint32_t xy;
@ -40,40 +43,60 @@ namespace DFHack
return false;
}
};
struct t_feature
{
e_feature type;
/// main material type - decides between stuff like bodily fluids, inorganics, vomit, amber, etc.
int16_t main_material;
/// generally some index to a vector of material types.
int32_t sub_material;
bool discovered; // placeholder.
/// placeholder
bool discovered;
/// this is NOT part of the DF feature, but an address of the feature as seen by DFhack.
uint32_t origin;
};
/// mineral vein object
struct t_vein
{
uint32_t vtable;
/// index into the inorganic material vector
int32_t type;
int16_t assignment[16];
/// bit mask describing how the vein maps to the map block
/// assignment[y] & (1 << x) describes the tile (x, y) of the block
int16_t assignment[16];
uint32_t flags;
uint32_t address_of; // this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
/// this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
uint32_t address_of;
};
// stores what tiles should appear when the ice melts
/// stores what tiles should appear when the ice melts
struct t_frozenliquidvein
{
uint32_t vtable;
/// a 16x16 array of the original tile types
int16_t tiles[16][16];
uint32_t address_of; // this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
/// this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
uint32_t address_of;
};
/// a 'spattervein' defines what coverings the individual map tiles have (snow, blood, etc)
/// @see PrintSplatterType in DFMiscUtils.h -- incomplete, but illustrative
struct t_spattervein
{
uint32_t vtable;
/// generic material.
uint16_t mat1;
uint16_t unk1;
/// material vector index
uint32_t mat2;
/// something even more specific?
uint16_t mat3;
/// 16x16 array of covering 'intensity'
uint8_t intensity[16][16];
uint32_t address_of; // this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
/// this is NOT part of the DF vein, but an address of the vein as seen by DFhack.
uint32_t address_of;
};
enum BiomeOffset
@ -98,16 +121,25 @@ namespace DFHack
traffic_restricted
};
/// type of a designation for a tile
enum e_designation
{
/// no designation
designation_no,
designation_default, // dig walls, remove stairs and ramps, gather plants, fell trees
designation_ud_stair, // dig up/down stairs
designation_channel, // dig a channel
designation_ramp, // dig ramp out of a wall
designation_d_stair, // dig a stair down
designation_u_stair, // dig a stair up
designation_7 // whatever
/// dig walls, remove stairs and ramps, gather plants, fell trees. depends on tile type
designation_default,
/// dig up/down stairs
designation_ud_stair,
/// dig a channel
designation_channel,
/// dig ramp out of a wall
designation_ramp,
/// dig a stair down
designation_d_stair,
/// dig a stair up
designation_u_stair,
/// whatever. for completenes I guess
designation_7
};
enum e_liquidtype
@ -120,41 +152,43 @@ namespace DFHack
{
unsigned int flow_size : 3; // how much liquid is here?
unsigned int pile : 1; // stockpile?
/*
* All the different dig designations... needs more info, probably an enum
*/
/// All the different dig designations
e_designation dig : 3;
unsigned int smooth : 2;
unsigned int hidden : 1;
/*
/**
* This one is rather involved, but necessary to retrieve the base layer matgloss index
* see http://www.bay12games.com/forum/index.php?topic=608.msg253284#msg253284 for details
* @see http://www.bay12games.com/forum/index.php?topic=608.msg253284#msg253284
*/
unsigned int geolayer_index :4;
unsigned int light : 1;
unsigned int subterranean : 1; // never seen the light of day?
unsigned int skyview : 1; // sky is visible now, it rains in here when it rains
/*
/**
* Probably similar to the geolayer_index. Only with a different set of offsets and different data.
* we don't use this yet
*/
unsigned int biome : 4;
/*
/**
* 0 = water
* 1 = magma
*/
e_liquidtype liquid_type : 1;
unsigned int water_table : 1; // srsly. wtf?
unsigned int rained : 1; // does this mean actual rain (as in the blue blocks) or a wet tile?
e_traffic traffic : 2; // needs enum
unsigned int flow_forbid : 1; // what?
e_traffic traffic : 2;
/// the tile is not evaluated when calculating flows?
unsigned int flow_forbid : 1;
/// no liquid spreading
unsigned int liquid_static : 1;
unsigned int feature_local : 1; // this tile is a part of a feature
unsigned int feature_global : 1; // this tile is a part of a feature
unsigned int liquid_character : 2; // those ripples on streams?
/// this tile is a part of a local feature. can be combined with 'featstone' tiles
unsigned int feature_local : 1;
/// this tile is a part of a global feature. can be combined with 'featstone' tiles
unsigned int feature_global : 1;
/// those ripples on streams?
unsigned int liquid_character : 2;
};
union t_designation
@ -166,12 +200,16 @@ namespace DFHack
// occupancy flags (rat,dwarf,horse,built wall,not build wall,etc)
struct naked_occupancy
{
unsigned int building : 3;// building type... should be an enum?
// building type... should be an enum?
// 7 = door
unsigned int building : 3;
/// the tile contains a standing? creature
unsigned int unit : 1;
/// the tile contains a prone creature
unsigned int unit_grounded : 1;
/// the tile contains an item
unsigned int item : 1;
// splatter. everyone loves splatter.
/// splatter. everyone loves splatter. this doesn't seem to be used anymore
unsigned int mud : 1;
unsigned int vomit :1;
unsigned int broken_arrows_color :4;
@ -199,12 +237,14 @@ namespace DFHack
struct naked_occupancy_grouped
{
unsigned int building : 3;// building type... should be an enum?
// 7 = door
unsigned int building : 3;
/// the tile contains a standing? creature
unsigned int unit : 1;
/// the tile contains a prone creature
unsigned int unit_grounded : 1;
/// the tile contains an item
unsigned int item : 1;
// splatter. everyone loves splatter.
/// splatter. everyone loves splatter. this doesn't seem to be used anymore
unsigned int splatter : 26;
};
@ -218,12 +258,15 @@ namespace DFHack
// map block flags
struct naked_blockflags
{
unsigned int designated : 1;// designated for jobs (digging and stuff like that)
unsigned int unk_1 : 1; // possibly related to the designated flag
// two flags required for liquid flow. no idea why
/// designated for jobs (digging and stuff like that)
unsigned int designated : 1;
/// possibly related to the designated flag
unsigned int unk_1 : 1;
/// two flags required for liquid flow.
unsigned int liquid_1 : 1;
unsigned int liquid_2 : 1;
unsigned int unk_2: 28; // rest of the flags is completely unknown
/// rest of the flags is completely unknown
unsigned int unk_2: 28;
// there's a possibility that this flags field is shorter than 32 bits
};
@ -241,13 +284,20 @@ namespace DFHack
typedef struct
{
/// type of the tiles
tiletypes40d tiletypes;
/// flags determining the state of the tiles
designations40d designation;
/// flags determining what's on the tiles
occupancies40d occupancy;
/// values used for geology/biome assignment
biome_indices40d biome_indices;
uint32_t origin; // the address where it came from
/// the address where the block came from
uint32_t origin;
t_blockflags blockflags;
/// index into the global feature vector
int16_t global_feature;
/// index into the local feature vector... complicated
int16_t local_feature;
} mapblock40d;
@ -321,6 +371,7 @@ namespace DFHack
* Return false/0 on failure, buffer allocated by client app, 256 items long
*/
bool isValidBlock(uint32_t blockx, uint32_t blocky, uint32_t blockz);
/**
* Get the address of a block or 0 if block is not valid
*/
@ -340,7 +391,7 @@ namespace DFHack
/// read/write temperatures
bool ReadTemperatures(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_temperatures *temp1, t_temperatures *temp2);
bool WriteTemperatures (uint32_t blockx, uint32_t blocky, uint32_t blockz, t_temperatures *temp1, t_temperatures *temp2);
/// read/write block occupancies
bool ReadOccupancy(uint32_t blockx, uint32_t blocky, uint32_t blockz, occupancies40d *buffer);
bool WriteOccupancy(uint32_t blockx, uint32_t blocky, uint32_t blockz, occupancies40d *buffer);
@ -350,10 +401,8 @@ namespace DFHack
bool WriteDirtyBit(uint32_t blockx, uint32_t blocky, uint32_t blockz, bool dirtybit);
/// read/write the block flags
bool ReadBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz,
t_blockflags &blockflags);
bool WriteBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz,
t_blockflags blockflags);
bool ReadBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_blockflags &blockflags);
bool WriteBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_blockflags blockflags);
/// read/write features
bool ReadFeatures(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t & local, int16_t & global);
bool WriteLocalFeature(uint32_t blockx, uint32_t blocky, uint32_t blockz, int16_t local = -1);
@ -368,7 +417,7 @@ namespace DFHack
std::vector<t_vein>* veins,
std::vector<t_frozenliquidvein>* ices = 0,
std::vector<t_spattervein>* splatter = 0);
private:
struct Private;
Private *d;

@ -25,10 +25,12 @@ distribution.
#ifndef MEMINFO_MANAGER_H_INCLUDED
#define MEMINFO_MANAGER_H_INCLUDED
#include "DFPragma.h"
#include "dfhack/DFPragma.h"
class TiXmlElement;
namespace DFHack
{
class memory_info;
class MemInfoManager
{
friend class ProcessEnumerator;

@ -19,16 +19,125 @@ using namespace std;
#endif
#include <DFHack.h>
class SegmentedFinder;
class SegmentFinder
{
public:
SegmentFinder(DFHack::t_memrange & mr, DFHack::Context * DF)
{
_DF = DF;
mr_ = mr;
mr_.buffer = (uint8_t *)malloc (mr_.end - mr_.start);
DF->ReadRaw(mr_.start,(mr_.end - mr_.start),mr_.buffer);
}
~SegmentFinder()
{
delete mr_.buffer;
}
template <class T, typename P >
bool Find (T needle, const uint8_t increment ,vector <uint64_t> &found, vector <uint64_t> &newfound, P oper)
{
if(found.empty())
{
//loop
for(uint64_t offset = 0; offset < (mr_.end - mr_.start) - sizeof(T); offset += increment)
{
if( (*(T *)(mr_.buffer + offset)) == needle)
newfound.push_back(mr_.start + offset);
}
}
else
{
for( uint64_t i = 0; i < found.size(); i++)
{
if(mr_.isInRange(found[i]))
{
uint64_t corrected = found[i] - mr_.start;
if( oper((T *)(mr_.buffer + corrected), needle) )
newfound.push_back(found[i]);
}
}
}
return true;
}
private:
friend class SegmentedFinder;
DFHack::Context * _DF;
DFHack::t_memrange mr_;
};
class SegmentedFinder
{
public:
SegmentedFinder(vector <DFHack::t_memrange>& ranges, DFHack::Context * DF)
{
_DF = DF;
for(int i = 0; i < ranges.size(); i++)
{
segments.push_back(new SegmentFinder(ranges[i], DF));
}
}
~SegmentedFinder()
{
for(int i = 0; i < segments.size(); i++)
{
delete segments[i];
}
}
SegmentFinder * getSegmentForAddress (uint64_t addr)
{
for(int i = 0; i < segments.size(); i++)
{
if(segments[i]->mr_.isInRange(addr))
{
return segments[i];
}
}
}
template<class T, typename P>
bool Find (const T dword, const uint8_t increment, vector <uint64_t> &found, vector <uint64_t> &newfound, P oper)
{
newfound.clear();
for(int i = 0; i < segments.size(); i++)
{
segments[i]->Find<T,P>(dword, increment, found, newfound, oper);
}
found.clear();
found = newfound;
return !(found.empty());
}
private:
DFHack::Context * _DF;
vector <SegmentFinder *> segments;
};
template <typename T>
bool equalityP (T *x, T y)
{
return (*x) == y;
}
typedef struct
{
uint32_t start;
uint32_t finish;
uint32_t alloc_finish;
} vecTriplet;
template <typename T>
bool vectorLength (T *x, T y)
{
return (*x) == y;
}
//TODO: lots of optimization
void searchLoop(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ranges, int size, int alignment)
{
int32_t test1;
int32_t test2;
vector <int64_t> found;
vector <int64_t> newfound;
found.reserve(100000);
newfound.reserve(100000);
uint32_t test1;
vector <uint64_t> found;
vector <uint64_t> newfound;
found.reserve(100);
newfound.reserve(100);
//bool initial = 1;
cout << "search ready - insert integers, 'p' for results" << endl;
string select;
@ -50,53 +159,45 @@ void searchLoop(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ran
DFMgr.Refresh();
DFHack::Context * DF = DFMgr.getSingleContext();
DF->Attach();
newfound.clear();
bool initial = found.empty();
if(initial)
SegmentedFinder sf(ranges,DF);
switch(size)
{
// for each range
for (int i = 0; i < ranges.size();i++)
{
// can't read? range is invalid to us
if(!ranges[i].read)
continue;
//loop
for(uint64_t offset = ranges[i].start;offset <= ranges[i].end - size; offset+=alignment)
{
DF->ReadRaw(offset, size, (uint8_t *) &test2);
if(test1 == test2 )
found.push_back(offset);
}
}
cout << "found " << found.size() << " addresses" << endl;
case 1:
sf.Find<uint8_t>(test1,alignment,found,newfound, equalityP<uint8_t>);
break;
case 2:
sf.Find<uint16_t>(test1,alignment,found,newfound, equalityP<uint16_t>);
break;
case 4:
sf.Find<uint32_t>(test1,alignment,found,newfound, equalityP<uint32_t>);
break;
}
else
if( found.size() == 1)
{
for(int j = 0; j < found.size();j++)
{
DF->ReadRaw(found[j], size, (uint8_t *) &test2);
if(test1 == test2)
{
newfound.push_back(found[j]);
}
}
cout << "matched " << newfound.size() << " addresses out of " << found.size() << endl;
found = newfound;
cout << "Found an address!" << endl;
cout << hex << "0x" << found[0] << endl;
}
else
cout << "Found " << dec << found.size() << " addresses." << endl;
DF->Detach();
}
else break;
}
}
typedef struct
/*
class VecVerifyPredicate
{
uint32_t start;
uint32_t finish;
uint32_t alloc_finish;
} vecTriplet;
public:
VecVerifyPredicate(){}
bool operator()(vecTriplet * vt, uint64_t length)
{
if(vt.start <= vt.finish && vt.finish <= vt.alloc_finish)
return true;
return false;
}
};
*/
void searchLoopVector(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ranges, uint32_t element_size)
{
vecTriplet load;
@ -190,7 +291,10 @@ void mkcopy(DFHack::ContextManager & DFMgr, vector <DFHack::t_memrange>& ranges,
DF->Detach();
DFMgr.purge();
}
inline void printRange(DFHack::t_memrange * tpr)
{
std::cout << std::hex << tpr->start << " - " << tpr->end << "|" << (tpr->read ? "r" : "-") << (tpr->write ? "w" : "-") << (tpr->execute ? "x" : "-") << "|" << tpr->name << std::endl;
}
int main (void)
{
string select;
@ -216,7 +320,7 @@ int main (void)
for(int i = 0; i< ranges.size();i++)
{
cout << dec << "(" << i << ") ";
ranges[i].print();
printRange(&(ranges[i]));
}
try_again_ranges:
@ -258,7 +362,7 @@ int main (void)
selected_ranges.insert(selected_ranges.begin(),ranges.begin() + start, ranges.begin() + end);
for(int i = 0; i< selected_ranges.size();i++)
{
selected_ranges[i].print();
printRange(&(selected_ranges[i]));
}
try_again_type:
cout << "Select search type: 1=number(default), 2=vector, 3=string" << endl;