#pragma once class UserProc; class DllProc; class CClass; class Schedule { public: enum Type { None = 10000, GlobalVar, // グローバル変数スケジュール DataTable, // データテーブル スケジュール CatchAddress, // Catchアドレス スケジュール Relocation, // リロケーション情報スケジュール UserProc, // ユーザ定義関数呼び出し側スケジュール AddressOf, // ユーザ定義関数位置スケジュール DllProc, // DLL関数位置スケジュール ComVtbl, // com_vtblスケジュール Vtbl, // vtblスケジュール TypeInfo, // TypeInfoスケジュール }; private: Type type; long offset; union{ LONG_PTR lpValue; const ::UserProc *pUserProc; const ::DllProc *pDllProc; const ::CClass *pClass; }; // 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: case CatchAddress: ar & boost::serialization::make_nvp("pUserProc", const_cast<::UserProc *&>(pUserProc)); break; case DllProc: ar & boost::serialization::make_nvp("pDllProc", const_cast<::DllProc *&>(pDllProc)); break; case ComVtbl: case Vtbl: case TypeInfo: ar & boost::serialization::make_nvp("pClass", const_cast<::CClass *&>(pClass)); 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( Schedule::Type type, const ::UserProc *pUserProc, long offset ) : type( type ) , offset( offset ) , pUserProc( pUserProc ) { } Schedule( const ::DllProc *pDllProc, long offset ) : type( Schedule::DllProc ) , offset( offset ) , pDllProc( pDllProc ) { } Schedule( Type type, const ::CClass *pClass, long offset ) : type( type ) , pClass( pClass ) , offset( offset ) { if( !( type == Schedule::ComVtbl || type == Schedule::Vtbl || type == Schedule::TypeInfo ) ) { DebugBreak(); } } Schedule(Schedule&& y) : type(std::move(y.type)) , offset(std::move(y.offset)) , lpValue(std::move(y.lpValue)) { } Schedule(Schedule const& y) : type(y.type) , offset(y.offset) , lpValue(y.lpValue) { } Schedule& operator =(Schedule&& y) { type = std::move(y.type); offset = std::move(y.offset); lpValue = std::move(y.lpValue); return *this; } Schedule& operator =(Schedule const& y) { return *this = std::move(Schedule(y)); } ~Schedule() { } Type GetType() const { return type; } long GetOffset() const { return offset; } LONG_PTR GetLongPtrValue() const { return lpValue; } const ::DllProc &GetDllProc() const; const ::UserProc &GetUserProc() const; const ::CClass &GetClass() const; virtual bool Resolve( const ObjectModule &resolver, ResolveErrors &resolveErrors ); }; typedef std::vector Schedules; #define CODETYPE_SYSTEMPROC 0x0001 #define CODETYPE_DEBUGPROC 0x0002 class SourceLine { long nativeCodePos; DWORD codeType; SourceCodePosition sourceCodePosition; // 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( nativeCodePos ); ar & BOOST_SERIALIZATION_NVP( codeType ); ar & BOOST_SERIALIZATION_NVP( sourceCodePosition ); } public: SourceLine( int nativeCodePos, DWORD codeType, const SourceCodePosition &sourceCodePosition ) : nativeCodePos( nativeCodePos ) , codeType( codeType ) , sourceCodePosition( sourceCodePosition ) { } SourceLine() { } SourceLine(SourceLine const& y) : nativeCodePos(y.nativeCodePos) , codeType(y.codeType) , sourceCodePosition(y.sourceCodePosition) { } SourceLine(SourceLine&& y) : nativeCodePos(std::move(y.nativeCodePos)) , codeType(std::move(y.codeType)) , sourceCodePosition(std::move(y.sourceCodePosition)) { } SourceLine& operator =(SourceLine&& y) { nativeCodePos = std::move(y.nativeCodePos); codeType = std::move(y.codeType); sourceCodePosition = std::move(y.sourceCodePosition); return *this; } SourceLine& operator =(SourceLine const& y) { return *this = std::move(SourceLine(y)); } long GetNativeCodePos() const { return nativeCodePos; } DWORD GetCodeType() const { return codeType; } const SourceCodePosition &GetSourceCodePosition() const { return sourceCodePosition; } SourceCodePosition &GetSourceCodePosition() { return sourceCodePosition; } void SetSourceCodePosition( const SourceCodePosition &sourceCodePosition ) { this->sourceCodePosition = sourceCodePosition; } bool IsInSystemProc() const { return ( (codeType&CODETYPE_SYSTEMPROC) != 0 ); } bool IsInDebugProc() const { return ( (codeType&CODETYPE_DEBUGPROC) != 0 ); } }; typedef std::vector SourceLines; class NativeCode : public Jenga::Common::Binary { // リンカで解決しなければならないスケジュール Schedules schedules; // ソースコード行番号とネイティブコード位置の対応情報 SourceLines sourceLines; // XMLシリアライズ用 private: friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int version) { trace_for_serialize( "serializing(load) - NativeCode" ); ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP( Jenga::Common::Binary ); ar & BOOST_SERIALIZATION_NVP( schedules ); ar & BOOST_SERIALIZATION_NVP( sourceLines ); } public: NativeCode() : Jenga::Common::Binary() { } NativeCode( const NativeCode &nativeCode ) : Jenga::Common::Binary() { PutEx( nativeCode ); } NativeCode( const char *codeBuffer, int size ) : Jenga::Common::Binary( codeBuffer, size ) { } ~NativeCode() { } void operator =( const NativeCode &nativeCode ) { Clear(); PutEx( nativeCode ); } const Schedules &GetSchedules() const { return schedules; } void PutEx( const NativeCode &nativeCode ); void PutEx( long l, Schedule::Type scheduleType ); void PutUserProcSchedule( const UserProc *pUserProc, bool isCall ); void PutCatchAddressSchedule( const UserProc *pUserProc, long codePos ); void PutDllProcSchedule( const DllProc *pDllProc ); void PutComVtblSchedule( const CClass *pClass ); void PutVtblSchedule( const CClass *pClass ); const SourceLines &GetSourceLines() const { return sourceLines; } void NextSourceLine( const SourceCodePosition &sourceCodePosition, bool isInSystemProc ); void ResetDataSectionBaseOffset( long dataSectionBaseOffset ); void ResetRelationalObjectModuleIndex( const std::vector &relationTable ); void Resolve( const ObjectModule &resolver, ResolveErrors &resolveErrors ); };