#include "stdafx.h" #include // データテーブルスケジュール void Linker::ResolveDataTableSchedules( long dataSectionBaseOffset ) { BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() ) { if( schedule.GetType() == Schedule::DataTable ) { nativeCode.Overwrite( schedule.GetOffset(), static_cast( nativeCode.GetLong( schedule.GetOffset() ) + imageBase + dataSectionBaseOffset ) ); } } } // DLL関数スケジュール void Linker::ResolveDllProcSchedules( long codeSectionBaseOffset, long importSectionBaseOffset, long lookupSize, long hintSize ) { BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() ) { if( schedule.GetType() == Schedule::DllProc ) { #ifdef _AMD64_ nativeCode.Overwrite( schedule.GetOffset(), static_cast( importSectionBaseOffset + schedule.GetDllProc().GetLookupAddress() - ( codeSectionBaseOffset + schedule.GetOffset() + sizeof(long) ) ) ); #else nativeCode.Overwrite( schedule.GetOffset(), static_cast( imageBase + importSectionBaseOffset + lookupSize + hintSize + schedule.GetDllProc().GetLookupAddress() ) ); #endif } } } // ユーザ定義関数スケジュール void Linker::ResolveUserProcSchedules( long codeSectionBaseOffset ) { BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() ) { if( schedule.GetType() == Schedule::UserProc || schedule.GetType() == Schedule::AddressOf ) { if( schedule.GetUserProc().GetBeginOpAddress() == 0 && schedule.GetUserProc().GetEndOpAddress() == 0 ) { SetError(); } if( schedule.GetType() == Schedule::UserProc ) { nativeCode.Overwrite( schedule.GetOffset(), static_cast( schedule.GetUserProc().GetBeginOpAddress() - ( schedule.GetOffset() + sizeof(long) ) ) ); } else if( schedule.GetType() == Schedule::AddressOf ) { nativeCode.Overwrite( schedule.GetOffset(), static_cast( schedule.GetUserProc().GetBeginOpAddress() + imageBase + codeSectionBaseOffset ) ); } } } } // グローバル変数スケジュール void Linker::ResolveGlobalVarSchedules( long rwSectionBaseOffset ) { int allInitVarSize = compiler.GetObjectModule().meta.GetGlobalVars().GetAllInitSize(); BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() ) { if( schedule.GetType() == Schedule::GlobalVar ) { if( nativeCode.GetLong( schedule.GetOffset() ) & 0x80000000 ) { nativeCode.Overwrite( schedule.GetOffset(), static_cast( allInitVarSize + (nativeCode.GetLong( schedule.GetOffset() ) & 0x7FFFFFFF) + imageBase + rwSectionBaseOffset ) ); } else { nativeCode.Overwrite( schedule.GetOffset(), static_cast( nativeCode.GetLong( schedule.GetOffset() ) + imageBase + rwSectionBaseOffset ) ); } } } } void Linker::ResolveVtblSchedule( long dataSectionBaseOffset ) { BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() ) { if( schedule.GetType() == Schedule::Vtbl ) { LONG_PTR vtblAddress = schedule.GetClass().GetVtblGlobalOffset(); nativeCode.Overwrite( schedule.GetOffset(), static_cast( vtblAddress + imageBase + dataSectionBaseOffset ) ); } } } void Linker::Link( ObjectModule &masterObjectModule ) { // nativeCodeは初期状態でなければならない if( nativeCode.GetSize() > 0 ) { SetError(); } nativeCode.Put( masterObjectModule.globalNativeCode ); masterObjectModule.meta.GetUserProcs().Iterator_Reset(); while( masterObjectModule.meta.GetUserProcs().Iterator_HasNext() ) { const UserProc *pUserProc = masterObjectModule.meta.GetUserProcs().Iterator_GetNext(); if( pUserProc->GetNativeCode().GetSize() > 0 ) { pUserProc->SetBeginOpAddress( nativeCode.GetSize() ); nativeCode.Put( pUserProc->GetNativeCode() ); pUserProc->SetEndOpAddress( nativeCode.GetSize() ); } } }