#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,const Type &type){ if(NATURAL_TYPE(type.GetBasicType())==DEF_OBJECT || NATURAL_TYPE(type.GetBasicType())==DEF_STRUCT){ lstrcpy(buffer+(*p),type.GetClass().GetName().c_str()); (*p)+=lstrlen(buffer+(*p))+1; } else{ *(LONG_PTR *)(buffer+(*p))=type.GetIndex(); (*p)+=sizeof(LONG_PTR); } } void GetLpIndex_DebugFile(char *buffer,int *p,Type &type){ if(NATURAL_TYPE(type.GetBasicType())==DEF_OBJECT || NATURAL_TYPE(type.GetBasicType())==DEF_STRUCT){ char szClassName[VN_SIZE]; lstrcpy(szClassName,buffer+(*p)); (*p)+=lstrlen(buffer+(*p))+1; type.SetIndex( (LONG_PTR)pobj_DBClass->Find(szClassName) ); } else{ type.SetIndex( *(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 INCLUDEFILEINFO IncludeFileInfo; int i2,i3,i4,i5,BufferSize; if(buffer){ HeapDefaultFree(buffer); buffer=0; } i2=0; extern char *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->GetName().c_str()); i2+=lstrlen(buffer+i2)+1; } ////////////////// // TypeDef情報 ////////////////// *(long *)(buffer+i2)=(int)Smoothie::Meta::typeDefs.size(); i2+=sizeof(long); for(i3=0;i3<(int)Smoothie::Meta::typeDefs.size();i3++){ lstrcpy(buffer+i2,Smoothie::Meta::typeDefs[i3].GetName().c_str() ); i2+=lstrlen(buffer+i2)+1; lstrcpy(buffer+i2,Smoothie::Meta::typeDefs[i3].GetBaseName().c_str() ); i2+=lstrlen(buffer+i2)+1; //バッファが足りない場合は再確保 if(BufferSizeGetName().c_str()); i2+=lstrlen(buffer+i2)+1; //型 *(long *)(buffer+i2)=pVar->GetBasicType(); i2+=sizeof(long); //型の拡張情報 SetLpIndex_DebugFile(buffer,&i2,*pVar); buffer[i2++] = pVar->IsRef() ? 1 : 0; buffer[i2++] = pVar->IsArray() ? 1 : 0; if(pVar->IsArray()){ for(i5=0;;i5++){ *(long *)(buffer+i2)=pVar->GetSubScriptsPtr()[i5]; i2+=sizeof(long); if(pVar->GetSubScriptsPtr()[i5]==-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(BufferSizeGetParentClassPtr()){ lstrcpy(buffer+i2,pUserProc->GetParentClassPtr()->GetName().c_str()); i2+=lstrlen(buffer+i2)+1; } else{ lstrcpy(buffer+i2,""); i2+=lstrlen(buffer+i2)+1; } //ID *(long *)(buffer+i2)=pUserProc->id; i2+=sizeof(long); //関数名 lstrcpy(buffer+i2,pUserProc->GetName().c_str()); i2+=lstrlen(buffer+i2)+1; *(long *)(buffer+i2)=pUserProc->beginOpAddress; i2+=sizeof(long); *(long *)(buffer+i2)=pUserProc->endOpAddress; i2+=sizeof(long); //ローカル変数情報 *(long *)(buffer+i2)=(int)pUserProc->localVars.size(); i2+=sizeof(long); //バッファが足りない場合は再確保 if(BufferSizelocalVars ){ lstrcpy(buffer+i2,pVar->GetName().c_str()); i2+=lstrlen(buffer+i2)+1; //型 *(long *)(buffer+i2)=pVar->GetBasicType(); i2+=sizeof(long); //型の拡張情報 SetLpIndex_DebugFile(buffer,&i2,*pVar); //参照型パラメータかどうか buffer[i2++] = pVar->IsRef() ? 1 : 0; //配列かどうか buffer[i2++] = pVar->IsArray() ? 1 : 0; //配列要素 if(pVar->IsArray()){ for(i5=0;;i5++){ *(long *)(buffer+i2)=pVar->GetSubScriptsPtr()[i5]; i2+=sizeof(long); if(pVar->GetSubScriptsPtr()[i5]==-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(BufferSizepNextData; } } /////////////////// // クラス情報 /////////////////// //イテレータをリセット pobj_DBClass->Iterator_Reset(); while(pobj_DBClass->Iterator_HasNext()){ CClass *pobj_c; pobj_c=pobj_DBClass->Iterator_GetNext(); //クラス名 lstrcpy(buffer+i2,pobj_c->GetName().c_str()); 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]->GetName().c_str()); 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]->GetBasicType(); i2+=sizeof(long); //型の拡張情報 SetLpIndex_DebugFile(buffer,&i2,*pobj_c->ppobj_Member[i4]); *(long *)(buffer+i2)=pobj_c->ppobj_Member[i4]->dwAccess; i2+=sizeof(long); //バッファが足りない場合は再確保 if(BufferSizemethods.size(); i2+=sizeof(long); foreach( const CMethod *pMethod, pobj_c->methods ){ *(long *)(buffer+i2)=pMethod->dwAccess; i2+=sizeof(long); if( pMethod->GetInheritsClassPtr() ){ lstrcpy(buffer+i2,pMethod->GetInheritsClassPtr()->GetName().c_str()); i2+=lstrlen(buffer+i2)+1; } else{ lstrcpy(buffer+i2,""); i2+=lstrlen(buffer+i2)+1; } lstrcpy(buffer+i2,pMethod->pUserProc->GetName().c_str()); 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->GetName().c_str()); i2+=lstrlen(buffer+i2)+1; memcpy(buffer+i2,member->SubScripts,sizeof(int)*MAX_ARRAYDIM); i2+=sizeof(int)*MAX_ARRAYDIM; //型 *(long *)(buffer+i2)=member->GetBasicType(); i2+=sizeof(long); //型の拡張情報 SetLpIndex_DebugFile(buffer,&i2,*member); *(long *)(buffer+i2)=member->dwAccess; i2+=sizeof(long); //バッファが足りない場合は再確保 if(BufferSizepobj_DBClass=new CDBClass(); int iMaxClassCount; iMaxClassCount=*(long *)(buffer+i2); i2+=sizeof(long); for(i3=0;i3AddClass(NamespaceScopes(),NamespaceScopesCollection(),buffer+i2,0); i2+=lstrlen(buffer+i2)+1; } extern CDBClass *pobj_DBClass; pobj_DBClass=this->pobj_DBClass; ////////////////// // TypeDef情報 ////////////////// //初期化 Smoothie::Meta::typeDefs.clear(); //個数を取得 num=*(long *)(buffer+i2); i2+=sizeof(long); for(i3=0;i3ppConstHash=ppConstHash; //グローバル変数情報 globalVars.clear(); int maxGlobalVars=*(long *)(buffer+i2); i2+=sizeof(long); for(i3=0;i3SetArray( SubScripts ); } //レキシカルスコープ情報 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); //変数を追加 globalVars.push_back( pVar ); } //グローバル実行領域のサイズ GlobalOpBufferSize=*(long *)(buffer+i2); i2+=sizeof(long); //プロシージャ情報 GlobalProc *pUserProc; SubNum=*(long *)(buffer+i2); i2+=sizeof(long); ppSubHash=(GlobalProc **)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,MAX_HASH*sizeof(GlobalProc *)); for(int i6=0;i6Find(szParentClassName); } //ID int id=*(long *)(buffer+i2); i2+=sizeof(long); //名前 char *name = buffer+i2; i2+=lstrlen(buffer+i2)+1; // オブジェクトを生成 // TODO: 名前空間が未完成 pUserProc = new GlobalProc( NamespaceScopes(), NamespaceScopesCollection(), name, Procedure::Function, false, false, false ); pUserProc->pNextData=0; pUserProc->id=id; pUserProc->SetParentClass( pClass ); pUserProc->beginOpAddress=*(long *)(buffer+i2); i2+=sizeof(long); pUserProc->endOpAddress=*(long *)(buffer+i2); i2+=sizeof(long); pUserProc->CompleteCompile(); //ローカル変数情報 pUserProc->localVars.clear(); int maxLocalVar=*(long *)(buffer+i2); i2+=sizeof(long); for(i3=0;i3SetArray( SubScripts ); } //レキシカルスコープ情報 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); //変数を追加 pUserProc->localVars.push_back( pVar ); } ///////////////////////////////// // 格納位置を計算してpUserProcをセット ///////////////////////////////// i4=hash_default(pUserProc->GetName().c_str()); GlobalProc *psi2; if(ppSubHash[i4]){ psi2=ppSubHash[i4]; while(1){ if(psi2->pNextData==0){ psi2->pNextData=pUserProc; break; } psi2=psi2->pNextData; } } else{ ppSubHash[i4]=pUserProc; } } //クラス情報 CClass *pobj_c; for(i3=0;i3( pobj_DBClass->Find(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]->SetName( (char *)(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; //型 Type type( *(long *)(buffer+i2) ); i2+=sizeof(long); //型の拡張情報 GetLpIndex_DebugFile(buffer,&i2,type); pobj_c->ppobj_Member[i4]->SetType( type.GetBasicType(), type.GetIndex() ); pobj_c->ppobj_Member[i4]->dwAccess=*(long *)(buffer+i2); i2+=sizeof(long); } //メソッド int nMethod = *(long *)(buffer+i2); i2+=sizeof(long); for( i4=0; i4Find(szInherits); } lstrcpy(temp2,buffer+i2); i2+=lstrlen(buffer+i2)+1; const CClass *pobj_temp_c; pobj_temp_c=pobj_InheritsClass; if(pobj_temp_c==0) pobj_temp_c=pobj_c; i5=hash_default(temp2); pUserProc=ppSubHash[i5]; while(1){ if( pUserProc->GetName() == temp2 &&pUserProc->GetParentClassPtr()==pobj_temp_c) break; pUserProc=pUserProc->pNextData; } CMethod *pMethod = new DynamicMethod( pUserProc, dwAccess, 0,0,false, pobj_InheritsClass); pobj_c->methods.push_back( pMethod ); } //静的メンバ int nStaticMember = *(long *)(buffer+i2); i2+=sizeof(long); for( i4=0; i4SetName( (char *)(buffer+i2) ); i2+=lstrlen(buffer+i2)+1; memcpy(member->SubScripts,buffer+i2,sizeof(int)*MAX_ARRAYDIM); i2+=sizeof(int)*MAX_ARRAYDIM; //型 Type type( *(long *)(buffer+i2) ); i2+=sizeof(long); //型の拡張情報 GetLpIndex_DebugFile(buffer,&i2,type); member->SetType( type.GetBasicType(), type.GetIndex() ); member->dwAccess=*(long *)(buffer+i2); i2+=sizeof(long); pobj_c->staticMembers.push_back( member ); } } HeapDefaultFree(buffer); buffer=0; extern GlobalProc **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 accessBytes; WriteProcessMemory(hDebugProcess,(void *)(ULONG_PTR)(dwImageBase+dwRVA_CodeSection), BreakStepCodeBuffer, SizeOf_CodeSection,&accessBytes); return 1; } BOOL CDebugSection::load(HMODULE hModule){ if(buffer){ HeapDefaultFree(buffer); buffer=0; } extern HANDLE hDebugProcess; SIZE_T accessBytes; IMAGE_DOS_HEADER ImageDosHeader; ReadProcessMemory(hDebugProcess,hModule,&ImageDosHeader,sizeof(IMAGE_DOS_HEADER),&accessBytes); 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,&accessBytes); 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), &accessBytes); 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; //ソースコード Smoothie::Lexical::source = source; //コードと行番号の関係 extern int MaxLineInfoNum; extern LINEINFO *pLineInfo; MaxLineInfoNum=this->MaxLineInfoNum; pLineInfo=this->pLineInfo; // クラス情報 extern CDBClass *pobj_DBClass; pobj_DBClass=this->pobj_DBClass; //定数を取得 extern CONSTINFO **ppConstHash; ppConstHash=this->ppConstHash; //グローバル実行領域のサイズ extern int GlobalOpBufferSize; GlobalOpBufferSize=this->GlobalOpBufferSize; //プロシージャ extern char **ppMacroNames; ppMacroNames=0; extern GlobalProc **ppSubHash; extern int SubNum; ppSubHash=this->ppSubHash; SubNum=this->SubNum; extern UserProc *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;i2load(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;