#include "stdafx.h" #include #include "../BasicCompiler_Common/common.h" #ifdef _AMD64_ #include "../BasicCompiler64/opcode.h" #else #include "../BasicCompiler32/opcode.h" #endif extern HANDLE hHeap; ///////////////////////////////////////////// // 再配置スケジュール // // メモリの再配置は.textセクション、または.dataセクションに行われることが予想される。 // .textセクション … セクションデータへのポインタ // .dataセクション … vtblの再配置 ///////////////////////////////////////////// CReloc *pobj_Reloc; CReloc::CReloc(){ buffer=0; length=0; NowPageRVAToReloc=0; } CReloc::~CReloc(){ AllFree(); } void CReloc::AllFree(void){ if(buffer){ HeapDefaultFree(buffer); buffer=0; } } void CReloc::copy(CReloc *por){ AllFree(); if(por->buffer){ buffer=(char *)HeapReAlloc(hHeap,0,buffer,por->length); memcpy(buffer,por->buffer,por->length); } else buffer=0; length=por->length; NowPageRVAToReloc=por->NowPageRVAToReloc; NowCountAddrToReloc=por->NowCountAddrToReloc; codeSectionAddresses = por->codeSectionAddresses; dataSectionAddresses = por->dataSectionAddresses; } void CReloc::AddSchedule_CodeSection(DWORD addr){ if( !compiler.IsDll() ) return; codeSectionAddresses.push_back( addr ); } void CReloc::AddSchedule_DataSection(DWORD addr){ if( !compiler.IsDll() ) return; dataSectionAddresses.push_back( addr ); } void CReloc::__add(DWORD addr){ if( !compiler.IsDll() ) return; BOOL sw; sw=0; while((addr-(addr%MEM_ALIGNMENT))>NowPageRVAToReloc){ NowPageRVAToReloc+=MEM_ALIGNMENT; sw=1; } if(sw){ //ページを増やす while(length%4){ buffer=(char *)HeapReAlloc(hHeap,0,buffer,length+sizeof(WORD)); (*(WORD *)(buffer+length))=0; length+=2; (*(DWORD *)(buffer+NowCountAddrToReloc))+=sizeof(WORD); } buffer=(char *)HeapReAlloc(hHeap,0,buffer, length+ sizeof(DWORD)+ sizeof(DWORD)); //Page RVA *(DWORD *)(buffer+length)=NowPageRVAToReloc; length+=sizeof(DWORD); NowCountAddrToReloc=length; //Block size *(DWORD *)(buffer+length)=sizeof(DWORD)*2; length+=sizeof(DWORD); } //リロケーション情報の追加 buffer=(char *)HeapReAlloc(hHeap,0,buffer,length+sizeof(WORD)); buffer[length]=0; buffer[length+1]=0x30; //=IMAGE_REL_BASED_HIGHLOW (*(WORD *)(buffer+length))|=addr&0x0FFF; length+=2; (*(DWORD *)(buffer+NowCountAddrToReloc))+=sizeof(WORD); } void CReloc::ResetRelocBuffer(void){ if(buffer) HeapDefaultFree(buffer); buffer=(char *)HeapAlloc(hHeap,0,1); length=0; NowPageRVAToReloc=0; BOOST_FOREACH( DWORD addr, codeSectionAddresses ) { extern int MemPos_CodeSection; __add(MemPos_CodeSection + addr); } BOOST_FOREACH( DWORD addr, dataSectionAddresses ) { extern int MemPos_DataSection; __add(MemPos_DataSection + addr); } } ////////////////////////// // 一般スケジュール ////////////////////////// CSchedule::CSchedule(){ pObpValues=(int *)HeapAlloc(hHeap,0,1); num=0; this->flag=0; } CSchedule::~CSchedule(){ HeapDefaultFree(pObpValues); } void CSchedule::SetFlag(int flag){ this->flag=flag; } void CSchedule::add(){ pObpValues=(int *)HeapReAlloc(hHeap,0,pObpValues,(num+1)*sizeof(int)); extern int obp; pObpValues[num]=obp; num++; if(flag&SCHEDULE_FLAG_RELOC){ //リロケーション情報を追加する pobj_Reloc->AddSchedule_CodeSection(obp); } } void CSchedule::move(int iStartPos,int iSize,int offset){ int i; for(i=0;iAddSchedule_CodeSection(obp); } } CSubAddrSchedule *pobj_SubAddrSchedule;