#include "stdafx.h" #include #include #include #include #include #include #include <../Enum.h> #include "../BasicCompiler_Common/common.h" #include "../BasicCompiler_Common/DebugSection.h" #include "Opcode.h" //////////////////////////// // 特殊関数の構造体ポインタ //////////////////////////// // グローバル関数、静的メソッド const UserProc *pSub_System_StartupProgram, *pSub_System_GlobalArea, *pSub_DebugSys_StartProc, *pSub_DebugSys_EndProc, *pSub_DebugSys_SaveContext, *pSub_System_GetEip, *pSub_System_InitDllGlobalVariables, *pSub_System_InitStaticLocalVariables, *pSub_System_Call_Destructor_of_GlobalObject, *pSub_System_End, *pSub_System_GetSp, *pSub_pow, *pSub_calloc, *pSub_realloc, *pSub_free, *pSub_System_GC_malloc_ForObject, *pSub_System_GC_malloc_ForObjectPtr, *pSub_System_GC_free_for_SweepingDelete, *pSubStaticMethod_System_TypeBase_InitializeUserTypes; // 動的メソッド const UserProc *pUserProc_System_CGarbageCollection_RegisterGlobalRoots; ////////////////////////////// // 各セクションの位置とサイズ int FileSize_CodeSection, FileSize_ExportSection, FileSize_ImportSection, FileSize_DataSection, FileSize_RWSection, FileSize_RSrcSection, FileSize_RelocSection, FileSize_DebugSection; int FilePos_CodeSection, FilePos_ExportSection, FilePos_ImportSection, FilePos_DataSection, FilePos_RWSection, FilePos_RSrcSection, FilePos_RelocSection, FilePos_DebugSection; int MemSize_CodeSection, MemSize_ExportSection, MemSize_ImportSection, MemSize_DataSection, MemSize_RWSection, MemSize_RSrcSection, MemSize_RelocSection, MemSize_DebugSection; int MemPos_CodeSection, MemPos_ExportSection, MemPos_ImportSection, MemPos_DataSection, MemPos_RWSection, MemPos_RSrcSection, MemPos_RelocSection, MemPos_DebugSection; int bUse_CodeSection, bUse_ExportSection, bUse_ImportSection, bUse_DataSection, bUse_RWSection, bUse_RSrcSection, bUse_RelocSection, bUse_DebugSection; void Compile(void){ extern HWND hMainDlg; extern HWND hOwnerEditor; extern HANDLE hHeap; extern BOOL bDebugCompile; extern DWORD ImageBase; extern int obp_AllocSize; extern char *basbuf; extern char OutputFileName[MAX_PATH]; int i,i2,i3,i4,i5; char temporary[MAX_PATH],*temp2; HANDLE hFile; //コードセクションのメモリ上の位置 MemPos_CodeSection= 0x1000; //データセクションのメモリ上の位置(仮定) MemPos_DataSection= 0x10000000; //エクスポート セクションを利用するかどうか if( compiler.IsDll() ) bUse_ExportSection=1; else bUse_ExportSection=0; // 静的リンク compiler.StaticLink( compiler.staticLibraries ); ////////////////// // データテーブル compiler.GetObjectModule().dataTable.Clear(); if(bDebugCompile){ compiler.GetObjectModule().dataTable.Add( (long)0x00000002 ); } ////////////////////// // コード生成前の準備 ////////////////////// //重複エラー情報管理のメモリを確保(グローバル領域コンパイル用) extern char **SynonymErrorWords; extern int SynonymErrorNum; SynonymErrorNum=0; SynonymErrorWords=(char **)HeapAlloc(hHeap,0,1); //列挙体に関する情報の初期化 CEnumParent::InitEnum(); //列挙体からクラスコードを生成 char *temp; temp=CEnumParent::GenerateCodes(); AddSourceCode(temp); HeapDefaultFree(temp); //関数ポインタ情報を初期化 compiler.GetObjectModule().meta.GetProcPointers().clear(); // 名前空間情報を取得 NamespaceSupporter::CollectNamespaces( compiler.GetObjectModule().GetCurrentSource().GetBuffer(), compiler.GetObjectModule().meta.GetNamespaces() ); //クラス名を取得(詳細情報はGetAllClassInfoで取得) // CollectProcedures関数の中で参照されるオブジェクト名を事前に取得する。 // ※オブジェクトの内容までは取得しない compiler.GetObjectModule().meta.GetClasses().CollectClassesForNameOnly( compiler.GetObjectModule().GetCurrentSource() ); //TypeDef情報を初期化 compiler.GetObjectModule().meta.GetTypeDefs().CollectTypeDefs(); //定数情報を取得 GetConstInfo(); //サブルーチン(ユーザー定義、DLL関数)の識別子、アドレスを取得 compiler.pCompilingClass = NULL; CollectProcedures( compiler.GetObjectModule().GetCurrentSource(), compiler.GetObjectModule().meta.GetUserProcs(), compiler.GetObjectModule().meta.GetDllProcs() ); // クラス情報を取得(※注 - CollectProceduresの後に呼び出す) compiler.GetObjectModule().meta.GetClasses().GetAllClassInfo(); // サブルーチン(ユーザー定義、DLL関数)のイテレータの準備 compiler.GetObjectModule().meta.GetUserProcs().Iterator_Init(); compiler.GetObjectModule().meta.GetDllProcs().Iterator_Init(); //コードと行番号の関係 extern SourceLines oldSourceLines; oldSourceLines.clear(); /////////////////////////// // 最低限必要な関数を取得 /////////////////////////// cp=-1; if(pSub_System_StartupProgram=GetSubHash("_System_StartupProgram",1)) pSub_System_StartupProgram->Using(); if(pSub_System_GlobalArea=GetSubHash(compiler.globalAreaProcName.c_str(),1)) { pSub_System_GlobalArea->Using(); pSub_System_GlobalArea->ThisIsAutoGenerationProc(); } if(pSub_DebugSys_StartProc=GetSubHash("_DebugSys_StartProc",1)) pSub_DebugSys_StartProc->Using(); if(pSub_DebugSys_EndProc=GetSubHash("_DebugSys_EndProc",1)) pSub_DebugSys_EndProc->Using(); if(pSub_DebugSys_SaveContext=GetSubHash("_DebugSys_SaveContext",1)) pSub_DebugSys_SaveContext->Using(); if(pSub_System_GetEip=GetSubHash("_System_GetEip",1)){ pSub_System_GetEip->Using(); pSub_System_GetEip->ThisIsSystemProc(); } if(pSub_System_InitDllGlobalVariables=GetSubHash("_System_InitDllGlobalVariables",1)){ pSub_System_InitDllGlobalVariables->Using(); pSub_System_InitDllGlobalVariables->ThisIsSystemProc(); } if(pSub_System_InitStaticLocalVariables=GetSubHash("_System_InitStaticLocalVariables",1)){ pSub_System_InitStaticLocalVariables->Using(); pSub_System_InitStaticLocalVariables->ThisIsSystemProc(); } if(pSub_System_Call_Destructor_of_GlobalObject=GetSubHash("_System_Call_Destructor_of_GlobalObject",1)){ pSub_System_Call_Destructor_of_GlobalObject->Using(); pSub_System_Call_Destructor_of_GlobalObject->ThisIsSystemProc(); } if(pSub_System_End=GetSubHash("_System_End",1)){ pSub_System_End->Using(); } if(pSub_System_GetSp=GetSubHash("_System_GetSp",1)){ pSub_System_GetSp->Using(); pSub_System_GetSp->ThisIsSystemProc(); } if(pSub_pow=GetSubHash("pow",1)) pSub_pow->Using(); if(pSub_calloc=GetSubHash("calloc",1)) pSub_calloc->Using(); if(pSub_realloc=GetSubHash("realloc",1)) pSub_realloc->Using(); if(pSub_free=GetSubHash("free",1)) pSub_free->Using(); if( pSub_System_GC_malloc_ForObject = GetSubHash( "_System_GC_malloc_ForObject",1 ) ) pSub_System_GC_malloc_ForObject->Using(); if( pSub_System_GC_malloc_ForObjectPtr = GetSubHash( "_System_GC_malloc_ForObjectPtr",1 ) ) pSub_System_GC_malloc_ForObjectPtr->Using(); if( pSub_System_GC_free_for_SweepingDelete = GetSubHash( "_System_GC_free_for_SweepingDelete",1 ) ) pSub_System_GC_free_for_SweepingDelete->Using(); if( pSubStaticMethod_System_TypeBase_InitializeUserTypes = GetSubHash( "ActiveBasic.Core._System_TypeBase.InitializeUserTypes",1 ) ){ pSubStaticMethod_System_TypeBase_InitializeUserTypes->Using(); pSubStaticMethod_System_TypeBase_InitializeUserTypes->ThisIsAutoGenerationProc(); } if( pUserProc_System_CGarbageCollection_RegisterGlobalRoots = GetClassMethod( "_System_CGarbageCollection", "RegisterGlobalRoots" ) ){ pUserProc_System_CGarbageCollection_RegisterGlobalRoots->Using(); pUserProc_System_CGarbageCollection_RegisterGlobalRoots->ThisIsAutoGenerationProc(); } //リロケーション情報 pobj_Reloc=new CReloc(); //レジスタのブロッキングを管理するためのオブジェクトを生成 pobj_BlockReg=new CBlockReg; //レキシカルスコープ情報を初期化 compiler.codeGenerator.lexicalScopes.Init(0); ///////////////////////////////////////////////////////////////// // デバッグコンパイル用のログを生成する ///////////////////////////////////////////////////////////////// #ifdef _DEBUG { ofstream ofs("middle_code.txt"); ofs << basbuf << endl; ofs.close(); } #endif ////////////////////// // グローバル実行領域 ////////////////////// cp=-1; UserProc::CompileStartForGlobalArea(); if( !compiler.IsDll() ){ // 名前空間が初期化されているかをチェック if( compiler.GetNamespaceSupporter().GetLivingNamespaceScopes().size() ){ SetError(); } //ラベル管理オブジェクトを初期化 compiler.codeGenerator.gotoLabels.clear(); //Gotoラベルスケジュール compiler.codeGenerator.gotoLabelSchedules.clear(); //With情報のメモリを確保 extern WITHINFO WithInfo; WithInfo.ppName=(char **)HeapAlloc(hHeap,0,1); WithInfo.pWithCp=(int *)HeapAlloc(hHeap,0,1); WithInfo.num=0; //Continueアドレスを初期化 compiler.codeGenerator.ClearContinueArea(); //スタックフレーム管理用クラスを選択 pobj_sf=new StackFrame(); // コード生成対象を選択 compiler.codeGenerator.Select( compiler.GetObjectModule().globalNativeCode ); trace_for_sourcecodestep( "★★★ グローバル領域のコンパイルを開始" ); //未完成 //breakpoint; if( compiler.IsCore() ) { //sub rsp,スタックフレームサイズ compiler.codeGenerator.op_sub_RV( sizeof(_int64), REG_RSP, 0x100 ); if(bDebugCompile){ //デバッグ用の変数を定義 DebugVariable(); } //GC用の変数を定義 InitGCVariables(); //_System_StartupProgramの呼び出し compiler.codeGenerator.op_call(pSub_System_StartupProgram); } // _System_GlobalArea の呼び出し compiler.codeGenerator.op_call( pSub_System_GlobalArea ); if( !compiler.IsStaticLibrary() ) { /////////////////////////////////////// // グローバル文字列変数の解放処理 /////////////////////////////////////// //call _System_End extern const UserProc *pSub_System_End; compiler.codeGenerator.op_call(pSub_System_End); //add rsp,スタックフレームサイズ compiler.codeGenerator.op_add_RV( REG_RSP, 0x100 ); //xor rax,rax(raxを0に初期化する) compiler.codeGenerator.op_zero_reg(REG_RAX); //ret compiler.codeGenerator.op_ret(); } //スタックフレームスケジュールを実行 pobj_sf->RunningSchedule( 0x100 ); delete pobj_sf; pobj_sf=0; //グローバル実行領域のコードサイズ extern int GlobalOpBufferSize; GlobalOpBufferSize = compiler.linker.GetNativeCode().GetSize(); //With情報のメモリを解放 for(i=0;iIsUsing() ){ continue; } /* //エラーチェック HINSTANCE hLib; hLib=LoadLibrary( pDllProc->GetDllFileName().c_str() ); if(!hLib){ extern char OutputFileName[MAX_PATH]; char temp2[MAX_PATH],temp3[MAX_PATH]; _splitpath(OutputFileName,temp2,temp3,NULL,NULL); lstrcat(temp2,temp3); lstrcpy(temp3,pDllProc->GetDllFileName().c_str()); GetFullPath(temp3,temp2); hLib=LoadLibrary(temp3); if(!hLib){ SetError(-106,pDllProc->GetDllFileName().c_str(),pDllProc->GetCodePos()); } } if(hLib){ if(!GetProcAddress(hLib,pDllProc->GetAlias().c_str())){ FreeLibrary(hLib); SetError(-107,pDllProc->GetAlias(),pDllProc->GetCodePos()); } FreeLibrary(hLib); } */ } ///////////////////////////// // リソースデータを読み込む ///////////////////////////// extern char ResourceFileName[MAX_PATH]; GetResourceData(ResourceFileName); ////////////////////////////// // エクスポート情報(DLLのみ) ////////////////////////////// IMAGE_EXPORT_DIRECTORY ImageExportDirectory; DWORD *lpdwExportAddressTable; DWORD *lpdwExportNamePointerTable; WORD *lpwExportOrdinalTable; char lpExportNames[8192]; int ExportNamesLength; int ExportNum; int DllMain_EntryPoint; DllMain_EntryPoint=-1; ExportNum=0; ExportNamesLength=0; lpdwExportAddressTable=(DWORD *)HeapAlloc(hHeap,0,1); lpdwExportNamePointerTable=(DWORD *)HeapAlloc(hHeap,0,1); lpwExportOrdinalTable=(WORD *)HeapAlloc(hHeap,0,1); if(bUse_ExportSection){ _splitpath(OutputFileName,NULL,NULL,lpExportNames,temporary); lstrcat(lpExportNames,temporary); ExportNamesLength=lstrlen(lpExportNames)+1; UserProc *pUserProc,*psi2; while(1){ //辞書順にサーチ temporary[0]=0; compiler.GetObjectModule().meta.GetUserProcs().Iterator_Reset(); while( compiler.GetObjectModule().meta.GetUserProcs().Iterator_HasNext() ) { pUserProc = compiler.GetObjectModule().meta.GetUserProcs().Iterator_GetNext(); if(pUserProc->IsExport()){ if(temporary[0]=='\0'){ lstrcpy(temporary,pUserProc->GetName().c_str()); psi2=pUserProc; } else{ i3=lstrlen(temporary); i4=(int)pUserProc->GetName().size(); if(i3GetName().c_str(),i3)>0){ lstrcpy(temporary,pUserProc->GetName().c_str()); psi2=pUserProc; } } } } if(psi2==0) break; pUserProc=psi2; pUserProc->ExportOff(); if( pUserProc->GetName() == "DllMain" ){ DllMain_EntryPoint = pUserProc->GetBeginOpAddress(); } lpdwExportAddressTable=(DWORD *)HeapReAlloc(hHeap,0,lpdwExportAddressTable,(ExportNum+1)*sizeof(DWORD)); lpdwExportAddressTable[ExportNum] = pUserProc->GetBeginOpAddress(); lpdwExportNamePointerTable=(DWORD *)HeapReAlloc(hHeap,0,lpdwExportNamePointerTable,(ExportNum+1)*sizeof(DWORD)); lpdwExportNamePointerTable[ExportNum]=ExportNamesLength; lpwExportOrdinalTable=(WORD *)HeapReAlloc(hHeap,0,lpwExportOrdinalTable,(ExportNum+1)*sizeof(WORD)); lpwExportOrdinalTable[ExportNum]=ExportNum; lstrcpy(lpExportNames+ExportNamesLength,pUserProc->GetName().c_str()); ExportNamesLength+=lstrlen(lpExportNames+ExportNamesLength)+1; ExportNum++; } for(i=0;iIsUsing() ){ continue; } if( pDllProc->GetDllFileName().size() > 16 ){ SetError(7,NULL,cp); break; } for(i2=0;i2GetDllFileName() == ppDllNames[i2] ){ break; } } if(i2==ImportDllNum){ ppDllNames=(char **)HeapReAlloc(hHeap,0,ppDllNames,(ImportDllNum+1)*sizeof(char **)); ppDllNames[ImportDllNum]=(char *)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,16); lstrcpy(ppDllNames[ImportDllNum],pDllProc->GetDllFileName().c_str()); ImportDllNum++; } } //IMAGE_IMPORT_DESCRIPTOR、及びルックアップ テーブル サイズの計算 IMAGE_IMPORT_DESCRIPTOR *pImportDescriptor; int LookupSize; LookupSize=0; pImportDescriptor=(IMAGE_IMPORT_DESCRIPTOR *)HeapAlloc(hHeap,0,(ImportDllNum+1)*sizeof(IMAGE_IMPORT_DESCRIPTOR)); for(i=0;iIsUsing() ){ continue; } if( pDllProc->GetDllFileName() == ppDllNames[i] ){ //ルックアップデータのサイズを追加 LookupSize+=sizeof(_int64); } } LookupSize+=sizeof(_int64); //NULL用 } memset(&pImportDescriptor[i],0,sizeof(IMAGE_IMPORT_DESCRIPTOR)); for(i=0;iIsUsing() ){ continue; } if( pDllProc->GetDllFileName() == ppDllNames[i] ){ //ルックアップの位置をセット(後にインポート アドレス テーブルにセットしなおされる) pDllProc->SetLookupAddress( i5*sizeof(_int64) ); //ルックアップ テーブルの値をセット pLookupTable[i5++]= LookupSize+ //インポート アドレス テーブル LookupSize+ //ルックアップテーブル (ImportDllNum+1)*sizeof(IMAGE_IMPORT_DESCRIPTOR)+ //IMAGE_IMPORT_DESCRIPTOR ImportDllNum*0x10+ //DLL名の羅列 HintSize; //ヒント名へのオフセット //ヒント テーブル pHintTable[HintSize++]=0; pHintTable[HintSize++]=0; lstrcpy(pHintTable+HintSize,pDllProc->GetAlias().c_str()); i4=(int)pDllProc->GetAlias().size(); HintSize+=i4+1; if(i4%2==0) pHintTable[HintSize++]=0; if(HintAllocSizeResetRelocBuffer(); } //グローバル変数情報を扱う構造体も初期バッファの有無による配置を行う //(デバッグ情報で利用される) BOOST_FOREACH( Variable *pVar, compiler.GetObjectModule().meta.GetGlobalVars() ){ if(pVar->GetOffsetAddress()&0x80000000){ pVar->SetOffsetAddress( (pVar->GetOffsetAddress()&0x7FFFFFFF) + compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.GetSize() ); } } //////////////////////////////////// // デバッグセクションを生成 //////////////////////////////////// //デバッグセクションを生成 CDebugSection *pobj_DebugSection; pobj_DebugSection=new CDebugSection(); extern BOOL bDebugCompile; extern BOOL bError; if(bDebugCompile&&bError==0){ pobj_DebugSection->make(); } ///////////////////////////////////// // 各セクションの位置とサイズを計算 ///////////////////////////////////// //コードセッションのファイル上のサイズ if(compiler.linker.GetNativeCode().GetSize()%FILE_ALIGNMENT) { FileSize_CodeSection = compiler.linker.GetNativeCode().GetSize() + (FILE_ALIGNMENT-compiler.linker.GetNativeCode().GetSize()%FILE_ALIGNMENT); } else { FileSize_CodeSection = compiler.linker.GetNativeCode().GetSize(); } if(FileSize_CodeSection) bUse_CodeSection=1; else bUse_CodeSection=0; //エクスポートセクションのファイル上のサイズ i= sizeof(IMAGE_EXPORT_DIRECTORY)+ //エクスポートディレクトリテーブルを飛び越す ExportNum*sizeof(DWORD)+ //エクスポート アドレス テーブルを飛び越す ExportNum*sizeof(DWORD)+ //エクスポート名ポインタ テーブルを飛び越す ExportNum*sizeof(WORD)+ //エクスポート序数テーブルを飛び越す ExportNamesLength; //シンボル名バッファ if(bUse_ExportSection){ if(i%FILE_ALIGNMENT) FileSize_ExportSection=i+(FILE_ALIGNMENT-i%FILE_ALIGNMENT); else FileSize_ExportSection=i; } else FileSize_ExportSection=0; //インポートセクションのファイル上のサイズ i= LookupSize+ //インポート アドレス テーブル LookupSize+ //ルックアップテーブル (ImportDllNum+1)*sizeof(IMAGE_IMPORT_DESCRIPTOR)+ //IMAGE_IMPORT_DESCRIPTOR ImportDllNum*0x10+ //DLL名の羅列 HintSize; //ヒント名 if(i%FILE_ALIGNMENT) FileSize_ImportSection=i+(FILE_ALIGNMENT-i%FILE_ALIGNMENT); else FileSize_ImportSection=i; bUse_ImportSection=1; //インポートセクションは必ず存在する //データセクションのファイル上のサイズ if(compiler.GetObjectModule().dataTable.GetSize()%FILE_ALIGNMENT) FileSize_DataSection=compiler.GetObjectModule().dataTable.GetSize()+(FILE_ALIGNMENT-compiler.GetObjectModule().dataTable.GetSize()%FILE_ALIGNMENT); else FileSize_DataSection=compiler.GetObjectModule().dataTable.GetSize(); if(FileSize_DataSection) bUse_DataSection=1; else bUse_DataSection=0; //リライタブルセクションのファイル上のサイズ(グローバル変数の初期情報のみを格納) if( compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.GetSize() % FILE_ALIGNMENT ) { FileSize_RWSection = compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.GetSize() + (FILE_ALIGNMENT-compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.GetSize()%FILE_ALIGNMENT); } else{ if( compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.GetSize() ) { FileSize_RWSection = compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.GetSize(); } else FileSize_RWSection=FILE_ALIGNMENT; } bUse_RWSection=1; //リソースセクションのファイル上のサイズ char *RSrcSectionBuffer; int RSrcSectionSize; RSrcSectionBuffer=GetRSrcSectionBuffer(&RSrcSectionSize); if(RSrcSectionSize%FILE_ALIGNMENT) FileSize_RSrcSection=RSrcSectionSize+(FILE_ALIGNMENT-RSrcSectionSize%FILE_ALIGNMENT); else FileSize_RSrcSection=RSrcSectionSize; if(FileSize_RSrcSection) bUse_RSrcSection=1; else bUse_RSrcSection=0; //リロケーションセクションのファイル上のサイズ if(pobj_Reloc->length%FILE_ALIGNMENT) FileSize_RelocSection=pobj_Reloc->length+(FILE_ALIGNMENT-pobj_Reloc->length%FILE_ALIGNMENT); else FileSize_RelocSection=pobj_Reloc->length; if(FileSize_RelocSection) bUse_RelocSection=1; else bUse_RelocSection=0; //デバッグセクションのファイル上のサイズ if(pobj_DebugSection->length%FILE_ALIGNMENT) FileSize_DebugSection=pobj_DebugSection->length+(FILE_ALIGNMENT-pobj_DebugSection->length%FILE_ALIGNMENT); else FileSize_DebugSection=pobj_DebugSection->length; if(FileSize_DebugSection) bUse_DebugSection=1; else bUse_DebugSection=0; //各セッションのファイル上の位置 FilePos_CodeSection= EXE_HEADER_SIZE; FilePos_ExportSection= FilePos_CodeSection+ FileSize_CodeSection; FilePos_ImportSection= FilePos_ExportSection+ FileSize_ExportSection; FilePos_DataSection= FilePos_ImportSection+ FileSize_ImportSection; FilePos_RWSection= FilePos_DataSection+ FileSize_DataSection; FilePos_RSrcSection= FilePos_RWSection+ FileSize_RWSection; FilePos_RelocSection= FilePos_RSrcSection+ FileSize_RSrcSection; FilePos_DebugSection= FilePos_RelocSection+ FileSize_RelocSection; //コードセッションのメモリ上のサイズ if(FileSize_CodeSection%MEM_ALIGNMENT) MemSize_CodeSection=FileSize_CodeSection+(MEM_ALIGNMENT-FileSize_CodeSection%MEM_ALIGNMENT); else MemSize_CodeSection=FileSize_CodeSection; //エクスポートセクションのメモリ上のサイズ if(FileSize_ExportSection%MEM_ALIGNMENT) MemSize_ExportSection=FileSize_ExportSection+(MEM_ALIGNMENT-FileSize_ExportSection%MEM_ALIGNMENT); else MemSize_ExportSection=FileSize_ExportSection; //インポートセクションのメモリ上のサイズ if(FileSize_ImportSection%MEM_ALIGNMENT) MemSize_ImportSection=FileSize_ImportSection+(MEM_ALIGNMENT-FileSize_ImportSection%MEM_ALIGNMENT); else MemSize_ImportSection=FileSize_ImportSection; //データセクションのメモリ上のサイズ if(FileSize_DataSection%MEM_ALIGNMENT) MemSize_DataSection=FileSize_DataSection+(MEM_ALIGNMENT-FileSize_DataSection%MEM_ALIGNMENT); else MemSize_DataSection=FileSize_DataSection; //リライタブルセクションのメモリ上のサイズ i = compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.GetSize() + compiler.GetObjectModule().meta.GetGlobalVars().GetAllSize(); if(i%MEM_ALIGNMENT) MemSize_RWSection=i+(MEM_ALIGNMENT-i%MEM_ALIGNMENT); else MemSize_RWSection=i; //リソースセクションのメモリ上のサイズ if(FileSize_RSrcSection%MEM_ALIGNMENT) MemSize_RSrcSection=FileSize_RSrcSection+(MEM_ALIGNMENT-FileSize_RSrcSection%MEM_ALIGNMENT); else MemSize_RSrcSection=FileSize_RSrcSection; //リロケーションセクションのメモリ上のサイズ if(FileSize_RelocSection%MEM_ALIGNMENT) MemSize_RelocSection=FileSize_RelocSection+(MEM_ALIGNMENT-FileSize_RelocSection%MEM_ALIGNMENT); else MemSize_RelocSection=FileSize_RelocSection; //デバッグセクションのメモリ上のサイズ if(FileSize_DebugSection%MEM_ALIGNMENT) MemSize_DebugSection=FileSize_DebugSection+(MEM_ALIGNMENT-FileSize_DebugSection%MEM_ALIGNMENT); else MemSize_DebugSection=FileSize_DebugSection; //各セッションのメモリ上の位置 if(bUse_ExportSection) MemPos_ExportSection= 0x1000+ MemSize_CodeSection; else MemPos_ExportSection=0; if(bUse_ImportSection) MemPos_ImportSection= 0x1000+ MemSize_CodeSection+ MemSize_ExportSection; else MemPos_ImportSection=0; if(bUse_DataSection) MemPos_DataSection= 0x1000+ MemSize_CodeSection+ MemSize_ExportSection+ MemSize_ImportSection; else MemPos_DataSection=0; if(bUse_RWSection) MemPos_RWSection= 0x1000+ MemSize_CodeSection+ MemSize_ExportSection+ MemSize_ImportSection+ MemSize_DataSection; else MemPos_RWSection=0; if(bUse_RSrcSection) MemPos_RSrcSection= 0x1000+ MemSize_CodeSection+ MemSize_ExportSection+ MemSize_ImportSection+ MemSize_DataSection+ MemSize_RWSection; else MemPos_RSrcSection=0; if(bUse_RelocSection) MemPos_RelocSection= 0x1000+ MemSize_CodeSection+ MemSize_ExportSection+ MemSize_ImportSection+ MemSize_DataSection+ MemSize_RWSection+ MemSize_RSrcSection; else MemPos_RelocSection=0; if(bUse_DebugSection) MemPos_DebugSection= 0x1000+ MemSize_CodeSection+ MemSize_ExportSection+ MemSize_ImportSection+ MemSize_DataSection+ MemSize_RWSection+ MemSize_RSrcSection+ MemSize_RelocSection; else MemPos_DebugSection=0; //////////////////////////// // エクスポート情報の再配置 //////////////////////////// if(bUse_ExportSection){ for(i=0;iIsUsing() ){ continue; } if( pDllProc->GetDllFileName() == ppDllNames[i] ){ //ルックアップ テーブル pLookupTable[i5++]+=MemPos_ImportSection; } } i5++; } //////////////////////////////////////// //仮想関数データテーブルスケジュール compiler.GetObjectModule().meta.GetClasses().ActionVtblSchedule(ImageBase,MemPos_CodeSection); if( compiler.IsDll() ){ //DLLの場合はリロケーション情報を生成 pobj_Reloc->ResetRelocBuffer(); } compiler.linker.SetImageBase( ImageBase ); compiler.linker.ResolveDataTableSchedules( MemPos_DataSection ); compiler.linker.ResolveDllProcSchedules( MemPos_CodeSection, MemPos_ImportSection, LookupSize, HintSize ); compiler.linker.ResolveUserProcSchedules( MemPos_CodeSection ); compiler.linker.ResolveGlobalVarSchedules( MemPos_RWSection ); compiler.linker.ResolveVtblSchedule( MemPos_DataSection ); //////////////////////////////// // リソースアドレススケジュール extern DWORD *lpdwRSrcAddrSchedule; extern int RSrcAddrScheduleNum; for(i=0;ilength; ImagePeHdr.OptionalHeader.DataDirectory[6].VirtualAddress=0; ImagePeHdr.OptionalHeader.DataDirectory[6].Size=0; ImagePeHdr.OptionalHeader.DataDirectory[7].VirtualAddress=0; ImagePeHdr.OptionalHeader.DataDirectory[7].Size=0; ImagePeHdr.OptionalHeader.DataDirectory[8].VirtualAddress=0; ImagePeHdr.OptionalHeader.DataDirectory[8].Size=0; ImagePeHdr.OptionalHeader.DataDirectory[9].VirtualAddress=0; ImagePeHdr.OptionalHeader.DataDirectory[9].Size=0; ImagePeHdr.OptionalHeader.DataDirectory[10].VirtualAddress=0; ImagePeHdr.OptionalHeader.DataDirectory[10].Size=0; ImagePeHdr.OptionalHeader.DataDirectory[11].VirtualAddress=0; ImagePeHdr.OptionalHeader.DataDirectory[11].Size=0; ImagePeHdr.OptionalHeader.DataDirectory[12].VirtualAddress=MemPos_ImportSection;//インポート アドレス テーブル ImagePeHdr.OptionalHeader.DataDirectory[12].Size=LookupSize; ImagePeHdr.OptionalHeader.DataDirectory[13].VirtualAddress=0; ImagePeHdr.OptionalHeader.DataDirectory[13].Size=0; ImagePeHdr.OptionalHeader.DataDirectory[14].VirtualAddress=0; ImagePeHdr.OptionalHeader.DataDirectory[14].Size=0; ImagePeHdr.OptionalHeader.DataDirectory[15].VirtualAddress=0; ImagePeHdr.OptionalHeader.DataDirectory[15].Size=0; //コードセクションヘッダ IMAGE_SECTION_HEADER CodeSectionHeader; memset((char *)CodeSectionHeader.Name,0,IMAGE_SIZEOF_SHORT_NAME); lstrcpy((char *)CodeSectionHeader.Name,".text"); CodeSectionHeader.Misc.VirtualSize= MemSize_CodeSection; CodeSectionHeader.VirtualAddress= MemPos_CodeSection; //開始アドレス CodeSectionHeader.SizeOfRawData= FileSize_CodeSection; CodeSectionHeader.PointerToRawData= FilePos_CodeSection; //ファイル上の開始アドレス CodeSectionHeader.PointerToRelocations= 0; CodeSectionHeader.PointerToLinenumbers= 0; CodeSectionHeader.NumberOfRelocations= 0; CodeSectionHeader.NumberOfLinenumbers= 0; CodeSectionHeader.Characteristics= IMAGE_SCN_MEM_EXECUTE| IMAGE_SCN_MEM_READ| IMAGE_SCN_CNT_CODE; //エクスポートセクションヘッダ IMAGE_SECTION_HEADER ExportSectionHeader; memset((char *)ExportSectionHeader.Name,0,IMAGE_SIZEOF_SHORT_NAME); lstrcpy((char *)ExportSectionHeader.Name,".edata"); ExportSectionHeader.Misc.VirtualSize= MemSize_ExportSection; ExportSectionHeader.VirtualAddress= MemPos_ExportSection; //開始アドレス ExportSectionHeader.SizeOfRawData= FileSize_ExportSection; //サイズ ExportSectionHeader.PointerToRawData= FilePos_ExportSection; //ファイル上の開始アドレス ExportSectionHeader.PointerToRelocations= 0; ExportSectionHeader.PointerToLinenumbers= 0; ExportSectionHeader.NumberOfRelocations= 0; ExportSectionHeader.NumberOfLinenumbers= 0; ExportSectionHeader.Characteristics= IMAGE_SCN_CNT_INITIALIZED_DATA| IMAGE_SCN_MEM_READ; //インポートセクションヘッダ IMAGE_SECTION_HEADER ImportSectionHeader; memset((char *)ImportSectionHeader.Name,0,IMAGE_SIZEOF_SHORT_NAME); lstrcpy((char *)ImportSectionHeader.Name,".idata"); ImportSectionHeader.Misc.VirtualSize= LookupSize+ //インポートアドレステーブル LookupSize+ //ルックアップテーブル (ImportDllNum+1)*sizeof(IMAGE_IMPORT_DESCRIPTOR)+ 16*ImportDllNum+ //DLL名 HintSize; //ヒント名(関数名)テーブル ImportSectionHeader.VirtualAddress= MemPos_ImportSection; //開始アドレス ImportSectionHeader.SizeOfRawData= FileSize_ImportSection; //サイズ ImportSectionHeader.PointerToRawData= FilePos_ImportSection; //ファイル上の開始アドレス ImportSectionHeader.PointerToRelocations= 0; ImportSectionHeader.PointerToLinenumbers= 0; ImportSectionHeader.NumberOfRelocations= 0; ImportSectionHeader.NumberOfLinenumbers= 0; ImportSectionHeader.Characteristics= IMAGE_SCN_CNT_INITIALIZED_DATA| IMAGE_SCN_MEM_READ; //データセクションヘッダ IMAGE_SECTION_HEADER DataSectionHeader; memset((char *)DataSectionHeader.Name,0,IMAGE_SIZEOF_SHORT_NAME); lstrcpy((char *)DataSectionHeader.Name,".sdata"); DataSectionHeader.Misc.VirtualSize= MemSize_DataSection; DataSectionHeader.VirtualAddress= MemPos_DataSection; DataSectionHeader.SizeOfRawData= FileSize_DataSection; DataSectionHeader.PointerToRawData= FilePos_DataSection; DataSectionHeader.PointerToRelocations= 0; DataSectionHeader.PointerToLinenumbers= 0; DataSectionHeader.NumberOfRelocations= 0; DataSectionHeader.NumberOfLinenumbers= 0; DataSectionHeader.Characteristics= IMAGE_SCN_CNT_INITIALIZED_DATA| IMAGE_SCN_MEM_READ| IMAGE_SCN_MEM_WRITE; //リライタブルセクションヘッダ IMAGE_SECTION_HEADER RWSectionHeader; memset((char *)RWSectionHeader.Name,0,IMAGE_SIZEOF_SHORT_NAME); lstrcpy((char *)RWSectionHeader.Name,".data"); RWSectionHeader.Misc.VirtualSize= compiler.GetObjectModule().meta.GetGlobalVars().initAreaBuffer.GetSize() + compiler.GetObjectModule().meta.GetGlobalVars().GetAllSize(); RWSectionHeader.VirtualAddress= MemPos_RWSection; RWSectionHeader.SizeOfRawData= FileSize_RWSection; RWSectionHeader.PointerToRawData= FilePos_RWSection; RWSectionHeader.PointerToRelocations= 0; RWSectionHeader.PointerToLinenumbers= 0; RWSectionHeader.NumberOfRelocations= 0; RWSectionHeader.NumberOfLinenumbers= 0; RWSectionHeader.Characteristics= IMAGE_SCN_CNT_INITIALIZED_DATA| IMAGE_SCN_MEM_READ| IMAGE_SCN_MEM_WRITE; //リソースセクションヘッダ IMAGE_SECTION_HEADER RSrcSectionHeader; memset((char *)RSrcSectionHeader.Name,0,IMAGE_SIZEOF_SHORT_NAME); lstrcpy((char *)RSrcSectionHeader.Name,".rsrc"); RSrcSectionHeader.Misc.VirtualSize= RSrcSectionSize; RSrcSectionHeader.VirtualAddress= MemPos_RSrcSection; RSrcSectionHeader.SizeOfRawData= FileSize_RSrcSection; RSrcSectionHeader.PointerToRawData= FilePos_RSrcSection; RSrcSectionHeader.PointerToRelocations= 0; RSrcSectionHeader.PointerToLinenumbers= 0; RSrcSectionHeader.NumberOfRelocations= 0; RSrcSectionHeader.NumberOfLinenumbers= 0; RSrcSectionHeader.Characteristics= IMAGE_SCN_CNT_INITIALIZED_DATA| IMAGE_SCN_MEM_READ; //リロケーションセクションヘッダ IMAGE_SECTION_HEADER RelocSectionHeader; memset((char *)RelocSectionHeader.Name,0,IMAGE_SIZEOF_SHORT_NAME); lstrcpy((char *)RelocSectionHeader.Name,".reloc"); RelocSectionHeader.Misc.VirtualSize= pobj_Reloc->length; RelocSectionHeader.VirtualAddress= MemPos_RelocSection; //開始アドレス RelocSectionHeader.SizeOfRawData= FileSize_RelocSection; //サイズ RelocSectionHeader.PointerToRawData= FilePos_RelocSection; //ファイル上の開始アドレス RelocSectionHeader.PointerToRelocations= 0; RelocSectionHeader.PointerToLinenumbers= 0; RelocSectionHeader.NumberOfRelocations= 0; RelocSectionHeader.NumberOfLinenumbers= 0; RelocSectionHeader.Characteristics= IMAGE_SCN_CNT_INITIALIZED_DATA| IMAGE_SCN_MEM_DISCARDABLE| IMAGE_SCN_MEM_READ; //デバッグセクションヘッダ IMAGE_SECTION_HEADER DebugSectionHeader; memset((char *)DebugSectionHeader.Name,0,IMAGE_SIZEOF_SHORT_NAME); lstrcpy((char *)DebugSectionHeader.Name,".debug"); DebugSectionHeader.Misc.VirtualSize= pobj_DebugSection->length; DebugSectionHeader.VirtualAddress= MemPos_DebugSection; //開始アドレス DebugSectionHeader.SizeOfRawData= FileSize_DebugSection; //サイズ DebugSectionHeader.PointerToRawData= FilePos_DebugSection; //ファイル上の開始アドレス DebugSectionHeader.PointerToRelocations= 0; DebugSectionHeader.PointerToLinenumbers= 0; DebugSectionHeader.NumberOfRelocations= 0; DebugSectionHeader.NumberOfLinenumbers= 0; DebugSectionHeader.Characteristics= IMAGE_SCN_MEM_DISCARDABLE| IMAGE_SCN_MEM_READ; hFile=CreateFile(OutputFileName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); if(hFile==INVALID_HANDLE_VALUE){ SetError(53,OutputFileName,-1); goto EndWriteOpcode; } //ヘッダ WriteFile(hFile,(void *)&ImageDosHeader,sizeof(IMAGE_DOS_HEADER),(DWORD *)&i2,NULL); i=i2; //Dosスタブ WriteFile(hFile,DosStubBuffer,DosStubSize,(DWORD *)&i2,NULL); i+=i2; //0x0100までNULLを並べる temp2=(char *)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,0x0100-i); WriteFile(hFile,temp2,0x0100-i,(DWORD *)&i2,NULL); HeapDefaultFree(temp2); i+=i2; //PEヘッダ WriteFile(hFile,&ImagePeHdr,sizeof(IMAGE_NT_HEADERS64),(DWORD *)&i2,NULL); i+=i2; //コード セクション ヘッダ WriteFile(hFile,&CodeSectionHeader,sizeof(IMAGE_SECTION_HEADER),(DWORD *)&i2,NULL); i+=i2; if(bUse_ExportSection){ //エクスポート セクション ヘッダ WriteFile(hFile,&ExportSectionHeader,sizeof(IMAGE_SECTION_HEADER),(DWORD *)&i2,NULL); i+=i2; } if(bUse_ImportSection){ //インポート セクション ヘッダ WriteFile(hFile,&ImportSectionHeader,sizeof(IMAGE_SECTION_HEADER),(DWORD *)&i2,NULL); i+=i2; } if(bUse_DataSection){ //データ セクション ヘッダ WriteFile(hFile,&DataSectionHeader,sizeof(IMAGE_SECTION_HEADER),(DWORD *)&i2,NULL); i+=i2; } if(bUse_RWSection){ //リライタブルセクションヘッダ WriteFile(hFile,&RWSectionHeader,sizeof(IMAGE_SECTION_HEADER),(DWORD *)&i2,NULL); i+=i2; } if(bUse_RSrcSection){ //リソースセクションヘッダ WriteFile(hFile,&RSrcSectionHeader,sizeof(IMAGE_SECTION_HEADER),(DWORD *)&i2,NULL); i+=i2; } if(bUse_RelocSection){ //リロケーションセクションヘッダ WriteFile(hFile,&RelocSectionHeader,sizeof(IMAGE_SECTION_HEADER),(DWORD *)&i2,NULL); i+=i2; } if(bUse_DebugSection){ //デバッグセクションヘッダ WriteFile(hFile,&DebugSectionHeader,sizeof(IMAGE_SECTION_HEADER),(DWORD *)&i2,NULL); i+=i2; } //EXE_HEADER_SIZEまでNULLを並べる temp2=(char *)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,EXE_HEADER_SIZE-i); WriteFile(hFile,temp2,EXE_HEADER_SIZE-i,(DWORD *)&i2,NULL); HeapDefaultFree(temp2); i+=i2; //コード WriteFile( hFile, compiler.linker.GetNativeCode().GetBuffer(), compiler.linker.GetNativeCode().GetSize(), (DWORD *)&i2, NULL ); i+=i2; //FilePos_ExportSectionまでNULLを並べる temp2=(char *)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,FilePos_ExportSection-i); WriteFile(hFile,temp2,FilePos_ExportSection-i,(DWORD *)&i2,NULL); HeapDefaultFree(temp2); i+=i2; if(bUse_ExportSection){ //エクスポート ディレクトリ テーブル WriteFile(hFile,&ImageExportDirectory,sizeof(IMAGE_EXPORT_DIRECTORY),(DWORD *)&i2,NULL); i+=i2; //エクスポート アドレス テーブル WriteFile(hFile,lpdwExportAddressTable,ExportNum*sizeof(DWORD),(DWORD *)&i2,NULL); i+=i2; //エクスポート名ポインタ テーブル WriteFile(hFile,lpdwExportNamePointerTable,ExportNum*sizeof(DWORD),(DWORD *)&i2,NULL); i+=i2; //エクスポート序数テーブル WriteFile(hFile,lpwExportOrdinalTable,ExportNum*sizeof(WORD),(DWORD *)&i2,NULL); i+=i2; //シンボル名 WriteFile(hFile,lpExportNames,ExportNamesLength,(DWORD *)&i2,NULL); i+=i2; } //FilePos_ImportSectionまでNULLを並べる temp2=(char *)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,FilePos_ImportSection-i); WriteFile(hFile,temp2,FilePos_ImportSection-i,(DWORD *)&i2,NULL); HeapDefaultFree(temp2); i+=i2; if(bUse_ImportSection){ //インポート アドレス テーブル WriteFile(hFile,pLookupTable,LookupSize,(DWORD *)&i2,NULL); i+=i2; //ルックアップ テーブル WriteFile(hFile,pLookupTable,LookupSize,(DWORD *)&i2,NULL); i+=i2; //インポート ディレクトリ テーブル(Nullディレクトリ テーブルを含む) for(i3=0;i3<(ImportDllNum+1);i3++){ WriteFile(hFile,&pImportDescriptor[i3],sizeof(IMAGE_IMPORT_DESCRIPTOR),(DWORD *)&i2,NULL); i+=i2; } //DLL名 for(i3=0;i3buffer,pobj_Reloc->length,(DWORD *)&i2,NULL); i+=i2; } //ファイルアラインメントを考慮 if(i%FILE_ALIGNMENT){ temp2=(char *)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,FILE_ALIGNMENT-i%FILE_ALIGNMENT); WriteFile(hFile,temp2,FILE_ALIGNMENT-i%FILE_ALIGNMENT,(DWORD *)&i2,NULL); HeapDefaultFree(temp2); i+=i2; } if(bUse_DebugSection){ //デバッグセクション WriteFile(hFile,pobj_DebugSection->buffer,pobj_DebugSection->length,(DWORD *)&i2,NULL); i+=i2; } //ファイルアラインメントを考慮 if(i%FILE_ALIGNMENT){ temp2=(char *)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,FILE_ALIGNMENT-i%FILE_ALIGNMENT); WriteFile(hFile,temp2,FILE_ALIGNMENT-i%FILE_ALIGNMENT,(DWORD *)&i2,NULL); HeapDefaultFree(temp2); i+=i2; } //書き込み終了 CloseHandle(hFile); EndWriteOpcode: //Dosスタブ用のメモリを解放 HeapDefaultFree(DosStubBuffer); //エクスポート テーブル情報を解放 HeapDefaultFree(lpdwExportAddressTable); HeapDefaultFree(lpdwExportNamePointerTable); HeapDefaultFree(lpwExportOrdinalTable); //インポートDLL情報を解放 HeapDefaultFree(pImportDescriptor); for(i=0;i