#pragma once #include #include #include class UserProc; class Schedule { public: enum Type { None = 10000, GlobalVar, // グローバル変数スケジュール DataTable, // データテーブル スケジュール Relocation, // リロケーション情報スケジュール UserProc, // ユーザ定義関数呼び出し側スケジュール AddressOf, // ユーザ定義関数位置スケジュール DllProc, // DLL関数位置スケジュール }; private: Type type; long offset; union{ LONG_PTR lpValue; const ::UserProc *pUserProc; const ::DllProc *pDllProc; }; // XMLシリアライズ用 private: friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int version) { trace_for_serialize( "serializing - Schedule" ); ar & BOOST_SERIALIZATION_NVP( type ); ar & BOOST_SERIALIZATION_NVP( offset ); switch( type ) { case UserProc: case AddressOf: ar & boost::serialization::make_nvp("pUserProc", const_cast<::UserProc *&>(pUserProc)); break; case DllProc: ar & boost::serialization::make_nvp("pDllProc", const_cast<::DllProc *&>(pDllProc)); break; default: ar & BOOST_SERIALIZATION_NVP( lpValue ); break; } } public: Schedule() { } Schedule( Type type, long offset, LONG_PTR lpValue = 0 ) : type( type ) , offset( offset ) , lpValue( lpValue ) { } Schedule( const ::UserProc *pUserProc, long offset ) : type( Schedule::UserProc ) , offset( offset ) , pUserProc( pUserProc ) { } Schedule( const ::DllProc *pDllProc, long offset ) : type( Schedule::DllProc ) , offset( offset ) , pDllProc( pDllProc ) { } ~Schedule() { } Type GetType() const { return type; } long GetOffset() const { return offset; } LONG_PTR GetLongPtrValue() const { return lpValue; } const ::DllProc &GetDllProc() const { if( type != Schedule::DllProc ) { SetError(); } return *pDllProc; } const ::UserProc &GetUserProc() const { if( !( type == Schedule::UserProc || type == Schedule::AddressOf ) ) { SetError(); } return *pUserProc; } void SpecifyAddressOf() { if( type != Schedule::UserProc ) { SetError(); } type = Schedule::AddressOf; } }; typedef std::vector Schedules; #define CODETYPE_SYSTEMPROC 0x0001 #define CODETYPE_DEBUGPROC 0x0002 class SourceLine { int lineNum; long nativeCodePos; long sourceCodePos; DWORD codeType; // XMLシリアライズ用 private: friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int version) { trace_for_serialize( "serializing - SourceLine" ); ar & BOOST_SERIALIZATION_NVP( lineNum ); ar & BOOST_SERIALIZATION_NVP( nativeCodePos ); ar & BOOST_SERIALIZATION_NVP( sourceCodePos ); ar & BOOST_SERIALIZATION_NVP( codeType ); } public: SourceLine( int lineNum, int nativeCodePos, int sourceCodePos, DWORD codeType ) : lineNum( lineNum ) , nativeCodePos( nativeCodePos ) , sourceCodePos( sourceCodePos ) , codeType( codeType ) { } SourceLine() { } int GetLineNum() const { return lineNum; } long GetNativeCodePos() const { return nativeCodePos; } long GetSourceCodePos() const { return sourceCodePos; } void SetSourceCodePos( int sourceCodePos ) { this->sourceCodePos = sourceCodePos; } DWORD GetCodeType() const { return codeType; } bool IsInSystemProc() const { return ( (codeType&CODETYPE_SYSTEMPROC) != 0 ); } bool IsInDebugProc() const { return ( (codeType&CODETYPE_DEBUGPROC) != 0 ); } }; typedef std::vector SourceLines; class NativeCode { int allocateSize; char *codeBuffer; int size; // リンカで解決しなければならないスケジュール Schedules schedules; // ソースコード行番号とネイティブコード位置の対応情報 SourceLines sourceLines; // XMLシリアライズ用 private: friend class boost::serialization::access; BOOST_SERIALIZATION_SPLIT_MEMBER(); template void load(Archive& ar, const unsigned int version) { trace_for_serialize( "serializing(load) - NativeCode" ); std::string code; ar & BOOST_SERIALIZATION_NVP( code ); ar & BOOST_SERIALIZATION_NVP( size ); ar & BOOST_SERIALIZATION_NVP( schedules ); ar & BOOST_SERIALIZATION_NVP( sourceLines ); // 読み込み後の処理 Realloc( size ); for( int i=0; i= 'a' ) ? ( code[i*3] - 'a' + 0x0a ) : ( code[i*3] - '0' ) ) * 0x10; ULONG_PTR l2 = ( code[i*3+1] >= 'a' ) ? ( code[i*3+1] - 'a' + 0x0a ) : ( code[i*3+1] - '0' ); ULONG_PTR l = l1 + l2; codeBuffer[i] = static_cast(l); } } template void save(Archive& ar, const unsigned int version) const { trace_for_serialize( "serializing(save) - NativeCode" ); // 保存準備 char *tempCode = (char *)calloc( (size+1) * 3, 1 ); for( int i=0; icodeBuffer+codePos); } void Overwrite( int codePos, char c ) { codeBuffer[codePos] = c; } void Overwrite( int codePos, long newLongValue ) { *(long *)(this->codeBuffer+codePos) = newLongValue; } void Put( const char *codeBuffer, int size ) { Realloc( this->size + size ); memcpy( this->codeBuffer + this->size, codeBuffer, size ); this->size += size; } void Put( const NativeCode &nativeCode ); void Put( _int64 i64data ) { Put( (const char *)(&i64data), sizeof(_int64) ); } void Put( long l, Schedule::Type scheduleType = Schedule::None ) { if( scheduleType != Schedule::None ) { schedules.push_back( Schedule( scheduleType, size ) ); } *((long *)(codeBuffer+size))=l; size += sizeof(long); } void PutUserProcSchedule( const UserProc *pUserProc, bool isCall ); void PutDllProcSchedule( const DllProc *pDllProc ); void Put( short s ) { Put( (const char *)(&s), sizeof(short) ); } void Put( char c ) { Realloc( size + 1 ); codeBuffer[size++] = c; } const SourceLines &GetSourceLines() const { return sourceLines; } void NextSourceLine(); void ResetDataSectionBaseOffset( long dataSectionBaseOffset ); };