#include "../BasicCompiler_Common/common.h" #ifdef _AMD64_ #include "../BasicCompiler64/opcode.h" #else #include "../BasicCompiler32/opcode.h" #endif #define MDLFILE_VER 0x70000003 void SetLpIndex_DebugFile(char *buffer,int *p,int type,LONG_PTR lpIndex){ if(NATURAL_TYPE(type)==DEF_OBJECT || NATURAL_TYPE(type)==DEF_STRUCT){ lstrcpy(buffer+(*p),((CClass *)lpIndex)->name); (*p)+=lstrlen(buffer+(*p))+1; } else{ *(LONG_PTR *)(buffer+(*p))=lpIndex; (*p)+=sizeof(LONG_PTR); } } void GetLpIndex_DebugFile(char *buffer,int *p,int type,LONG_PTR *plpIndex){ if(NATURAL_TYPE(type)==DEF_OBJECT || NATURAL_TYPE(type)==DEF_STRUCT){ char szClassName[VN_SIZE]; lstrcpy(szClassName,buffer+(*p)); (*p)+=lstrlen(buffer+(*p))+1; *plpIndex=(LONG_PTR)pobj_DBClass->check(szClassName); } else{ *plpIndex=*(LONG_PTR *)(buffer+(*p)); (*p)+=sizeof(LONG_PTR); } } CDebugSection::CDebugSection(){ memset(this,0,sizeof(CDebugSection)); } CDebugSection::~CDebugSection(){ if(pobj_DBClass) DeleteDebugInfo(); if(buffer){ HeapDefaultFree(buffer); buffer=0; } } void CDebugSection::make(void){ extern VARIABLE *GlobalVar; extern int MaxGlobalVarNum; extern INCLUDEFILEINFO IncludeFileInfo; int i2,i3,i4,i5,BufferSize; if(buffer){ HeapDefaultFree(buffer); buffer=0; } i2=0; extern char *basbuf; i3=lstrlen(basbuf); BufferSize=lstrlen(basbuf)+65535; buffer=(char *)HeapAlloc(hHeap,0,BufferSize); //デバッグ用ファイルのバージョン *(long *)(buffer+i2)=MDLFILE_VER; i2+=sizeof(long); //プラットフォームのビット数 *(long *)(buffer+i2)=PLATFORM; i2+=sizeof(long); //インクルード情報 *(long *)(buffer+i2)=IncludeFileInfo.FilesNum; i2+=sizeof(long); for(i3=0;i3Iterator_Reset(); //個数 *(long *)(buffer+i2)=pobj_DBClass->Iterator_GetMaxCount(); i2+=sizeof(long); while(pobj_DBClass->Iterator_HasNext()){ CClass *pobj_c; pobj_c=pobj_DBClass->Iterator_GetNext(); //クラス名 lstrcpy(buffer+i2,pobj_c->name); i2+=lstrlen(buffer+i2)+1; } ////////////////// // TypeDef情報 ////////////////// extern CDBTypeDef *pobj_DBTypeDef; *(long *)(buffer+i2)=pobj_DBTypeDef->iNum; i2+=sizeof(long); for(i3=0;i3iNum;i3++){ lstrcpy(buffer+i2,pobj_DBTypeDef->ppobj_TypeDef[i3]->lpszName); i2+=lstrlen(buffer+i2)+1; lstrcpy(buffer+i2,pobj_DBTypeDef->ppobj_TypeDef[i3]->lpszBaseName); i2+=lstrlen(buffer+i2)+1; //バッファが足りない場合は再確保 if(BufferSizename); i2+=lstrlen(buffer+i2)+1; //型 *(long *)(buffer+i2)=pVar->type; i2+=sizeof(long); //型の拡張情報 SetLpIndex_DebugFile(buffer,&i2,pVar->type,pVar->u.index); buffer[i2++]=(char)pVar->fRef; buffer[i2++]=(char)pVar->bArray; if(pVar->bArray){ for(i4=0;;i4++){ *(long *)(buffer+i2)=pVar->SubScripts[i4]; i2+=sizeof(long); if(pVar->SubScripts[i4]==-1) break; } } //レキシカルスコープ情報 *(long *)(buffer+i2)=pVar->ScopeStartAddress; i2+=sizeof(long); *(long *)(buffer+i2)=pVar->ScopeEndAddress; i2+=sizeof(long); *(long *)(buffer+i2)=pVar->ScopeLevel; i2+=sizeof(long); //メモリ位置 *(long *)(buffer+i2)=pVar->offset; i2+=sizeof(long); //バッファが足りない場合は再確保 if(BufferSizepobj_ParentClass){ lstrcpy(buffer+i2,psi->pobj_ParentClass->name); i2+=lstrlen(buffer+i2)+1; } else{ lstrcpy(buffer+i2,""); i2+=lstrlen(buffer+i2)+1; } //ID *(long *)(buffer+i2)=psi->id; i2+=sizeof(long); //関数名 lstrcpy(buffer+i2,psi->name); i2+=lstrlen(buffer+i2)+1; *(long *)(buffer+i2)=psi->CompileAddress; i2+=sizeof(long); *(long *)(buffer+i2)=psi->EndOpAddr; i2+=sizeof(long); *(long *)(buffer+i2)=psi->bVirtual; i2+=sizeof(long); //ローカル変数情報 *(long *)(buffer+i2)=psi->VarNum; i2+=sizeof(long); //バッファが足りない場合は再確保 if(BufferSizeVarNum;i4++){ VARIABLE *pVar=&psi->pVar[i4]; lstrcpy(buffer+i2,pVar->name); i2+=lstrlen(buffer+i2)+1; //型 *(long *)(buffer+i2)=pVar->type; i2+=sizeof(long); //型の拡張情報 SetLpIndex_DebugFile(buffer,&i2,pVar->type,pVar->u.index); //参照型パラメータかどうか buffer[i2++]=(char)pVar->fRef; //配列かどうか buffer[i2++]=(char)pVar->bArray; //配列要素 if(pVar->bArray){ for(i5=0;;i5++){ *(long *)(buffer+i2)=pVar->SubScripts[i5]; i2+=sizeof(long); if(pVar->SubScripts[i5]==-1) break; } } else pVar->SubScripts[0]=-1; //レキシカルスコープ情報 *(long *)(buffer+i2)=pVar->ScopeStartAddress; i2+=sizeof(long); *(long *)(buffer+i2)=pVar->ScopeEndAddress; i2+=sizeof(long); *(long *)(buffer+i2)=pVar->ScopeLevel; i2+=sizeof(long); //メモリ位置 *(long *)(buffer+i2)=pVar->offset; i2+=sizeof(long); //バッファが足りない場合は再確保 if(BufferSizepNextData; } } /////////////////// // クラス情報 /////////////////// //イテレータをリセット pobj_DBClass->Iterator_Reset(); while(pobj_DBClass->Iterator_HasNext()){ CClass *pobj_c; pobj_c=pobj_DBClass->Iterator_GetNext(); //クラス名 lstrcpy(buffer+i2,pobj_c->name); i2+=lstrlen(buffer+i2)+1; //仮想関数の数 *(long *)(buffer+i2)=pobj_c->vtbl_num; i2+=sizeof(long); //アラインメント *(long *)(buffer+i2)=pobj_c->iAlign; i2+=sizeof(long); //メンバ *(long *)(buffer+i2)=pobj_c->iMemberNum; i2+=sizeof(long); for(i4=0;i4iMemberNum;i4++){ lstrcpy(buffer+i2,pobj_c->ppobj_Member[i4]->name); i2+=lstrlen(buffer+i2)+1; memcpy(buffer+i2,pobj_c->ppobj_Member[i4]->SubScripts,sizeof(int)*MAX_ARRAYDIM); i2+=sizeof(int)*MAX_ARRAYDIM; //型 *(long *)(buffer+i2)=pobj_c->ppobj_Member[i4]->TypeInfo.type; i2+=sizeof(long); //型の拡張情報 SetLpIndex_DebugFile(buffer,&i2,pobj_c->ppobj_Member[i4]->TypeInfo.type,pobj_c->ppobj_Member[i4]->TypeInfo.u.lpIndex); *(long *)(buffer+i2)=pobj_c->ppobj_Member[i4]->dwAccess; i2+=sizeof(long); //バッファが足りない場合は再確保 if(BufferSizemethods.size(); i2+=sizeof(long); foreach( CMethod *method, pobj_c->methods ){ *(long *)(buffer+i2)=method->dwAccess; i2+=sizeof(long); if(method->pobj_InheritsClass){ lstrcpy(buffer+i2,method->pobj_InheritsClass->name); i2+=lstrlen(buffer+i2)+1; } else{ lstrcpy(buffer+i2,""); i2+=lstrlen(buffer+i2)+1; } lstrcpy(buffer+i2,method->psi->name); i2+=lstrlen(buffer+i2)+1; } //静的メンバ *(long *)(buffer+i2)=(long)pobj_c->staticMembers.size(); i2+=sizeof(long); foreach( CMember *member, pobj_c->staticMembers ){ lstrcpy(buffer+i2,member->name); i2+=lstrlen(buffer+i2)+1; memcpy(buffer+i2,member->SubScripts,sizeof(int)*MAX_ARRAYDIM); i2+=sizeof(int)*MAX_ARRAYDIM; //型 *(long *)(buffer+i2)=member->TypeInfo.type; i2+=sizeof(long); //型の拡張情報 SetLpIndex_DebugFile(buffer,&i2,member->TypeInfo.type,member->TypeInfo.u.lpIndex); *(long *)(buffer+i2)=member->dwAccess; i2+=sizeof(long); //バッファが足りない場合は再確保 if(BufferSizebasbuf; //コードと行番号の関係 MaxLineInfoNum=*(long *)(buffer+i2); i2+=sizeof(long); pLineInfo=(LINEINFO *)HeapAlloc(hHeap,0,MaxLineInfoNum*sizeof(LINEINFO)+1); memcpy(pLineInfo,buffer+i2,MaxLineInfoNum*sizeof(LINEINFO)); i2+=MaxLineInfoNum*sizeof(LINEINFO); /////////////////////////////////////////// // クラス情報(名前のみ。詳細は後で取得) /////////////////////////////////////////// this->pobj_DBClass=new CDBClass(); int iMaxClassCount; iMaxClassCount=*(long *)(buffer+i2); i2+=sizeof(long); for(i3=0;i3AddClass(buffer+i2,0); i2+=lstrlen(buffer+i2)+1; } extern CDBClass *pobj_DBClass; pobj_DBClass=this->pobj_DBClass; ////////////////// // TypeDef情報 ////////////////// //初期化 pobj_DBTypeDef=new CDBTypeDef; //個数を取得 num=*(long *)(buffer+i2); i2+=sizeof(long); for(i3=0;i3add(temp5,buffer+i2); i2+=lstrlen(buffer+i2)+1; } extern CDBTypeDef *pobj_DBTypeDef; pobj_DBTypeDef=this->pobj_DBTypeDef; //定数を取得 GetConstInfo(); extern CONSTINFO **ppConstHash; this->ppConstHash=ppConstHash; //グローバル変数情報 MaxGlobalVarNum=*(long *)(buffer+i2); i2+=sizeof(long); GlobalVar=(VARIABLE *)HeapAlloc(hHeap,0,MaxGlobalVarNum*sizeof(VARIABLE)+1); for(i3=0;i3name,buffer+i2); i2+=lstrlen(buffer+i2)+1; pVar->type=*(long *)(buffer+i2); i2+=sizeof(long); GetLpIndex_DebugFile(buffer,&i2,pVar->type,&pVar->u.index); pVar->fRef=(long)buffer[i2++]; pVar->bArray=(long)buffer[i2++]; if(pVar->bArray){ for(i4=0;;i4++){ pVar->SubScripts[i4]=*(long *)(buffer+i2); i2+=sizeof(long); if(pVar->SubScripts[i4]==-1) break; } } //レキシカルスコープ情報 pVar->ScopeStartAddress=*(long *)(buffer+i2); i2+=sizeof(long); pVar->ScopeEndAddress=*(long *)(buffer+i2); i2+=sizeof(long); pVar->ScopeLevel=*(long *)(buffer+i2); i2+=sizeof(long); //メモリ位置 pVar->offset=*(long *)(buffer+i2); i2+=sizeof(long); } //グローバル実行領域のサイズ GlobalOpBufferSize=*(long *)(buffer+i2); i2+=sizeof(long); //プロシージャ情報 SUBINFO *psi; SubNum=*(long *)(buffer+i2); i2+=sizeof(long); ppSubHash=(SUBINFO **)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,MAX_HASH*sizeof(SUBINFO *)); for(i3=0;i3pNextData=0; char szParentClassName[VN_SIZE]; lstrcpy(szParentClassName,buffer+i2); i2+=lstrlen(buffer+i2)+1; if(szParentClassName[0]) psi->pobj_ParentClass=pobj_DBClass->check(szParentClassName); else psi->pobj_ParentClass=0; //ID psi->id=*(long *)(buffer+i2); i2+=sizeof(long); //名前 psi->name=(char *)HeapAlloc(hHeap,0,lstrlen(buffer+i2)+1); lstrcpy(psi->name,buffer+i2); i2+=lstrlen(buffer+i2)+1; psi->CompileAddress=*(long *)(buffer+i2); i2+=sizeof(long); psi->EndOpAddr=*(long *)(buffer+i2); i2+=sizeof(long); psi->bVirtual=*(long *)(buffer+i2); i2+=sizeof(long); psi->ParmNum=0; psi->pParmInfo=0; psi->RealParmNum=0; psi->pRealParmInfo=0; psi->bCompile=1; //ローカル変数情報 psi->VarNum=*(long *)(buffer+i2); i2+=sizeof(long); psi->pVar=(VARIABLE *)HeapAlloc(hHeap,0,psi->VarNum*sizeof(VARIABLE)+1); for(i4=0;i4VarNum;i4++){ VARIABLE *pVar=&psi->pVar[i4]; //ローカル変数名 lstrcpy(pVar->name,buffer+i2); i2+=lstrlen(buffer+i2)+1; //型 pVar->type=*(long *)(buffer+i2); i2+=sizeof(long); //型の拡張情報 GetLpIndex_DebugFile(buffer,&i2,pVar->type,&pVar->u.index); //参照型パラメータかどうか pVar->fRef=(long)buffer[i2++]; //配列かどうか pVar->bArray=(long)buffer[i2++]; if(pVar->bArray){ for(i5=0;;i5++){ //配列要素 pVar->SubScripts[i5]=*(long *)(buffer+i2); i2+=sizeof(long); if(pVar->SubScripts[i5]==-1) break; } } //レキシカルスコープ情報 pVar->ScopeStartAddress=*(long *)(buffer+i2); i2+=sizeof(long); pVar->ScopeEndAddress=*(long *)(buffer+i2); i2+=sizeof(long); pVar->ScopeLevel=*(long *)(buffer+i2); i2+=sizeof(long); //メモリ上の位置 pVar->offset=*(long *)(buffer+i2); i2+=sizeof(long); } ///////////////////////////////// // 格納位置を計算してpsiをセット ///////////////////////////////// i4=hash_default(psi->name); SUBINFO *psi2; if(ppSubHash[i4]){ psi2=ppSubHash[i4]; while(1){ if(psi2->pNextData==0){ psi2->pNextData=psi; break; } psi2=psi2->pNextData; } } else{ ppSubHash[i4]=psi; } } //クラス情報 CClass *pobj_c; for(i3=0;i3check(szClassName); //仮想関数の数 pobj_c->vtbl_num=*(long *)(buffer+i2); i2+=sizeof(long); //アラインメント pobj_c->iAlign=*(long *)(buffer+i2); i2+=sizeof(long); //メンバ pobj_c->iMemberNum=*(long *)(buffer+i2); i2+=sizeof(long); pobj_c->ppobj_Member= (CMember **)HeapAlloc(hHeap,0,pobj_c->iMemberNum*sizeof(CMember *)); for(i4=0;i4iMemberNum;i4++){ pobj_c->ppobj_Member[i4]=new CMember(); pobj_c->ppobj_Member[i4]->name=(char *)HeapAlloc(hHeap,0,lstrlen(buffer+i2)+1); lstrcpy(pobj_c->ppobj_Member[i4]->name,buffer+i2); i2+=lstrlen(buffer+i2)+1; memcpy(pobj_c->ppobj_Member[i4]->SubScripts,buffer+i2,sizeof(int)*MAX_ARRAYDIM); i2+=sizeof(int)*MAX_ARRAYDIM; //型 pobj_c->ppobj_Member[i4]->TypeInfo.type=*(long *)(buffer+i2); i2+=sizeof(long); //型の拡張情報 GetLpIndex_DebugFile(buffer,&i2,pobj_c->ppobj_Member[i4]->TypeInfo.type,&pobj_c->ppobj_Member[i4]->TypeInfo.u.lpIndex); pobj_c->ppobj_Member[i4]->dwAccess=*(long *)(buffer+i2); i2+=sizeof(long); } //メソッド int nMethod = *(long *)(buffer+i2); i2+=sizeof(long); for( i4=0; i4dwAccess=*(long *)(buffer+i2); i2+=sizeof(long); char szInherits[VN_SIZE]; lstrcpy(szInherits,buffer+i2); i2+=lstrlen(buffer+i2)+1; if(szInherits[0]) method->pobj_InheritsClass=pobj_DBClass->check(szInherits); else method->pobj_InheritsClass=0; lstrcpy(temp2,buffer+i2); i2+=lstrlen(buffer+i2)+1; CClass *pobj_temp_c; pobj_temp_c=method->pobj_InheritsClass; if(pobj_temp_c==0) pobj_temp_c=pobj_c; i5=hash_default(temp2); psi=ppSubHash[i5]; while(1){ if(lstrcmp(psi->name,temp2)==0&&psi->pobj_ParentClass==pobj_temp_c) break; psi=psi->pNextData; } method->psi=psi; pobj_c->methods.push_back( method ); } //静的メンバ int nStaticMember = *(long *)(buffer+i2); i2+=sizeof(long); for( i4=0; i4name=(char *)HeapAlloc(hHeap,0,lstrlen(buffer+i2)+1); lstrcpy(member->name,buffer+i2); i2+=lstrlen(buffer+i2)+1; memcpy(member->SubScripts,buffer+i2,sizeof(int)*MAX_ARRAYDIM); i2+=sizeof(int)*MAX_ARRAYDIM; //型 member->TypeInfo.type=*(long *)(buffer+i2); i2+=sizeof(long); //型の拡張情報 GetLpIndex_DebugFile(buffer,&i2,member->TypeInfo.type,&member->TypeInfo.u.lpIndex); member->dwAccess=*(long *)(buffer+i2); i2+=sizeof(long); pobj_c->staticMembers.push_back( member ); } } HeapDefaultFree(buffer); buffer=0; extern SUBINFO **ppSubHash; ppSubHash=this->ppSubHash; pSub_DebugSys_EndProc=GetSubHash("_DebugSys_EndProc"); SingleStepCodeBuffer=MakeSingleStepCode(); ///////////////////////////// // ブレークポイントを適用 ///////////////////////////// //インクルード情報 extern INCLUDEFILEINFO IncludeFileInfo; IncludeFileInfo=this->IncludeFileInfo; //コードと行番号の関係 extern int MaxLineInfoNum; extern LINEINFO *pLineInfo; MaxLineInfoNum=this->MaxLineInfoNum; pLineInfo=this->pLineInfo; BreakStepCodeBuffer=pobj_DBBreakPoint->update(OpBuffer,SizeOf_CodeSection); //プロセスメモリにコピー extern HANDLE hDebugProcess; SIZE_T stAccBytes; WriteProcessMemory(hDebugProcess,(void *)(ULONG_PTR)(dwImageBase+dwRVA_CodeSection), BreakStepCodeBuffer, SizeOf_CodeSection,&stAccBytes); return 1; } BOOL CDebugSection::load(HMODULE hModule){ if(buffer){ HeapDefaultFree(buffer); buffer=0; } extern HANDLE hDebugProcess; SIZE_T stAccBytes; IMAGE_DOS_HEADER ImageDosHeader; ReadProcessMemory(hDebugProcess,hModule,&ImageDosHeader,sizeof(IMAGE_DOS_HEADER),&stAccBytes); int pe_size; #ifdef _AMD64_ IMAGE_NT_HEADERS64 pe_hdr; pe_size=sizeof(IMAGE_NT_HEADERS64); #else IMAGE_NT_HEADERS pe_hdr; pe_size=sizeof(IMAGE_NT_HEADERS); #endif ReadProcessMemory(hDebugProcess,(void *)(((ULONG_PTR)hModule)+ImageDosHeader.e_lfanew),&pe_hdr,pe_size,&stAccBytes); IMAGE_SECTION_HEADER *pSectionHdr; pSectionHdr=(IMAGE_SECTION_HEADER *)HeapAlloc(hHeap,0,pe_hdr.FileHeader.NumberOfSections*sizeof(IMAGE_SECTION_HEADER)); ReadProcessMemory(hDebugProcess, (void *)(((ULONG_PTR)hModule)+ImageDosHeader.e_lfanew+pe_size), pSectionHdr, pe_hdr.FileHeader.NumberOfSections*sizeof(IMAGE_SECTION_HEADER), &stAccBytes); int i; for(i=0;idwImageBase; //リライタブルセクションのRVA extern int MemPos_RWSection; MemPos_RWSection=this->dwRVA_RWSection; //コードセクションのRVAとサイズ extern int MemPos_CodeSection; extern int FileSize_CodeSection; MemPos_CodeSection=this->dwRVA_CodeSection; FileSize_CodeSection=this->SizeOf_CodeSection; //インクルード情報 extern INCLUDEFILEINFO IncludeFileInfo; IncludeFileInfo=this->IncludeFileInfo; //ソースコード extern char *pBaseBuffer; extern char *basbuf; pBaseBuffer=this->pBaseBuffer; basbuf=this->basbuf; //コードと行番号の関係 extern int MaxLineInfoNum; extern LINEINFO *pLineInfo; MaxLineInfoNum=this->MaxLineInfoNum; pLineInfo=this->pLineInfo; // クラス情報 extern CDBClass *pobj_DBClass; pobj_DBClass=this->pobj_DBClass; // TypeDef情報 extern CDBTypeDef *pobj_DBTypeDef; pobj_DBTypeDef=this->pobj_DBTypeDef; //定数を取得 extern CONSTINFO **ppConstHash; ppConstHash=this->ppConstHash; //グローバル変数に関する情報 extern VARIABLE *GlobalVar; extern int MaxGlobalVarNum; GlobalVar=this->GlobalVar; MaxGlobalVarNum=this->MaxGlobalVarNum; //グローバル実行領域のサイズ extern int GlobalOpBufferSize; GlobalOpBufferSize=this->GlobalOpBufferSize; //プロシージャ extern char **ppMacroNames; ppMacroNames=0; extern SUBINFO **ppSubHash; extern int SubNum; ppSubHash=this->ppSubHash; SubNum=this->SubNum; extern SUBINFO *pSub_DebugSys_EndProc; pSub_DebugSys_EndProc=this->pSub_DebugSys_EndProc; //ネイティブコードバッファ extern char *OpBuffer; OpBuffer=this->OpBuffer; } void CDebugSection::DeleteDebugInfo(void){ int i2; //インクルード情報を解放 for(i2=0;i2bCompile) HeapDefaultFree(psi->pVar); psi=psi->pNextData; } } //クラスに関するメモリを解放 delete pobj_DBClass; pobj_DBClass=0; //サブルーチン情報のメモリ解放 DeleteSubInfo(ppSubHash,0,0); //定数に関する情報を解放 DeleteConstInfo(ppConstHash); //ソースコードを解放 HeapDefaultFree(pBaseBuffer); //コードと行番号の関係を解放 HeapDefaultFree(pLineInfo); //コードバッファを解放 HeapDefaultFree(OpBuffer); OpBuffer=0; HeapDefaultFree(SingleStepCodeBuffer); SingleStepCodeBuffer=0; HeapDefaultFree(BreakStepCodeBuffer); BreakStepCodeBuffer=0; } CDBDebugSection::CDBDebugSection(){ ppobj_ds=(CDebugSection **)HeapAlloc(hHeap,0,1); num=0; } CDBDebugSection::~CDBDebugSection(){ int i; for(i=0;iload(hModule)){ //デバッグ情報が存在しないとき delete pobj_d; return 0; } ppobj_ds=(CDebugSection **)HeapReAlloc(hHeap,0,ppobj_ds,(num+1)*sizeof(CDebugSection *)); ppobj_ds[num]=pobj_d; num++; return 1; } void CDBDebugSection::del(HMODULE hModule){ int i; for(i=0;idwImageBase==hModule){ delete ppobj_ds[i]; num--; for(;ichoice(); } CDBDebugSection *pobj_DBDebugSection;