#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 ) ); } } BOOST_FOREACH( const Schedule &schedule, dataTable.schedules ) { if( schedule.GetType() == Schedule::DataTable ) { #ifdef _WIN64 dataTable.OverwriteInt64( schedule.GetOffset(), dataTable.GetInt64( schedule.GetOffset() ) + imageBase + dataSectionBaseOffset ); #else dataTable.Overwrite( schedule.GetOffset(), dataTable.GetLong( schedule.GetOffset() ) + imageBase + dataSectionBaseOffset ); #endif } } } // Catchアドレス スケジュール void Linker::ResolveCatchAddressSchedules( long codeSectionBaseOffset ) { BOOST_FOREACH( const Schedule &schedule, nativeCode.GetSchedules() ) { if( schedule.GetType() == Schedule::CatchAddress ) { if( nativeCode.GetLong( schedule.GetOffset() ) != 0 ) { // 置き換える値が0の場合を除く nativeCode.Overwrite( schedule.GetOffset(), static_cast( nativeCode.GetLong( schedule.GetOffset() ) + schedule.GetUserProc().GetBeginOpAddress() + imageBase + codeSectionBaseOffset ) ); } } } BOOST_FOREACH( const Schedule &schedule, dataTable.schedules ) { if( schedule.GetType() == Schedule::CatchAddress ) { if( nativeCode.GetLong( schedule.GetOffset() ) != 0 ) { // 置き換える値が0の場合を除く #ifdef _WIN64 dataTable.OverwriteInt64( schedule.GetOffset(), dataTable.GetInt64( schedule.GetOffset() ) + schedule.GetUserProc().GetBeginOpAddress() + imageBase + codeSectionBaseOffset ); #else dataTable.Overwrite( schedule.GetOffset(), dataTable.GetLong( schedule.GetOffset() ) + schedule.GetUserProc().GetBeginOpAddress() + imageBase + codeSectionBaseOffset ); #endif } } } } // 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().initAreaBuffer.GetSize(); 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 vtblMasterListOffset = schedule.GetClass().GetVtblMasterListOffset(); nativeCode.Overwrite( schedule.GetOffset(), static_cast( vtblMasterListOffset + imageBase + dataSectionBaseOffset ) ); } } BOOST_FOREACH( const Schedule &schedule, dataTable.schedules ) { if( schedule.GetType() == Schedule::Vtbl ) { LONG_PTR vtblMasterListOffset = schedule.GetClass().GetVtblMasterListOffset(); #ifdef _WIN64 dataTable.OverwriteInt64( schedule.GetOffset(), vtblMasterListOffset + imageBase + dataSectionBaseOffset ); #else dataTable.Overwrite( schedule.GetOffset(), vtblMasterListOffset + imageBase + dataSectionBaseOffset ); #endif } } } void Linker::ResolveTypeInfoSchedule( long dataSectionBaseOffset ) { BOOST_FOREACH( const Schedule &schedule, dataTable.schedules ) { if( schedule.GetType() == Schedule::TypeInfo ) { LONG_PTR typeInfoDataTableOffset = schedule.GetClass().GetTypeInfoDataTableOffset(); #ifdef _WIN64 dataTable.OverwriteInt64( schedule.GetOffset(), typeInfoDataTableOffset + imageBase + dataSectionBaseOffset ); #else dataTable.Overwrite( schedule.GetOffset(), typeInfoDataTableOffset + imageBase + dataSectionBaseOffset ); #endif } } } void Linker::Link( ObjectModule &masterObjectModule ) { // nativeCodeは初期状態でなければならない if( nativeCode.GetSize() > 0 ) { SetError(); } nativeCode.PutEx( 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.PutEx( pUserProc->GetNativeCode() ); pUserProc->SetEndOpAddress( nativeCode.GetSize() ); } } } void Linker::SetDataTable( DataTable &dataTable ) { this->dataTable.Add( dataTable ); }