source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/DebugMiddleFile.cpp@ 824

Last change on this file since 824 was 750, checked in by イグトランス (egtra), 16 years ago

BOOST_FOREACHを可能なものはVC++ 2005 for eachへ置換(やや速くなる)。

File size: 11.1 KB
RevLine 
[206]1#include "stdafx.h"
2
3#include "../BasicCompiler_Common/DebugSection.h"
[4]4
5#ifdef _AMD64_
[485]6#include "../compiler_x64/opcode.h"
[4]7#else
[484]8#include "../compiler_x86/opcode.h"
[4]9#endif
10
11#define MDLFILE_VER 0x70000003
12
[598]13using namespace ActiveBasic::Compiler;
[4]14
[598]15
[75]16void SetLpIndex_DebugFile(char *buffer,int *p,const Type &type){
17 if(NATURAL_TYPE(type.GetBasicType())==DEF_OBJECT || NATURAL_TYPE(type.GetBasicType())==DEF_STRUCT){
[131]18 lstrcpy(buffer+(*p),type.GetClass().GetName().c_str());
[4]19 (*p)+=lstrlen(buffer+(*p))+1;
20 }
21 else{
[75]22 *(LONG_PTR *)(buffer+(*p))=type.GetIndex();
[4]23 (*p)+=sizeof(LONG_PTR);
24 }
25}
26
27
[75]28void GetLpIndex_DebugFile(char *buffer,int *p,Type &type){
29 if(NATURAL_TYPE(type.GetBasicType())==DEF_OBJECT || NATURAL_TYPE(type.GetBasicType())==DEF_STRUCT){
[4]30 char szClassName[VN_SIZE];
31 lstrcpy(szClassName,buffer+(*p));
32 (*p)+=lstrlen(buffer+(*p))+1;
33
[598]34 type.SetClassPtr(
35 compiler.GetObjectModule().meta.GetClasses().FindEx( LexicalAnalyzer::FullNameToSymbol( szClassName ) )
36 );
[4]37 }
38 else{
[75]39 type.SetIndex( *(LONG_PTR *)(buffer+(*p)) );
[4]40 (*p)+=sizeof(LONG_PTR);
41 }
42}
43
44
45
[741]46DebugSection::~DebugSection(){
[265]47 if(dwImageBase) DeleteDebugInfo();
[4]48 if(buffer){
49 HeapDefaultFree(buffer);
50 buffer=0;
51 }
52}
[743]53void DebugSection::make( const SourceLines &sourceLines )
54{
[279]55 int i2,BufferSize;
[4]56
57 if(buffer){
58 HeapDefaultFree(buffer);
59 buffer=0;
60 }
61
62 i2=0;
63
64 extern char *basbuf;
65 BufferSize=lstrlen(basbuf)+65535;
66 buffer=(char *)HeapAlloc(hHeap,0,BufferSize);
67
68 //デバッグ用ファイルのバージョン
69 *(long *)(buffer+i2)=MDLFILE_VER;
70 i2+=sizeof(long);
71
72 //プラットフォームのビット数
73 *(long *)(buffer+i2)=PLATFORM;
74 i2+=sizeof(long);
75
[264]76
77 // オブジェクトモジュール
78 {
79 // テキストデータにシリアライズ
[587]80 std::string textString;
81 compiler.GetObjectModule().WriteString( textString );
[264]82
83 // サイズ
[587]84 *(long *)(buffer+i2) = (long)textString.size();
[264]85 i2+=sizeof(long);
86
87 //バッファが足りない場合は再確保
[587]88 if(BufferSize<i2+(int)textString.size()+32768){
89 while( BufferSize<i2+(int)textString.size()+32768 )
[264]90 {
91 BufferSize+=32768;
92 }
93
94 buffer=(char *)HeapReAlloc(hHeap,0,buffer,BufferSize);
95 }
96
97 // バッファ
[587]98 memcpy( buffer+i2, textString.c_str(), textString.size() );
99 i2 += (int)textString.size();
[264]100 }
101
[636]102 // オブジェクトモジュールリストに類似したソースコードリスト
103 {
104 // オブジェクトモジュールリストに類似したソースコードリストを作成
105 BasicSources sources;
[750]106 foreach( const ObjectModule *pObjectModule, compiler.staticLibraries )
[636]107 {
108 sources.push_back( pObjectModule->GetSource() );
109 }
[264]110
[636]111 // テキストデータにシリアライズ
112 std::string textString;
113 sources.WriteBinaryString( textString );
114
115 // サイズ
116 *(long *)(buffer+i2) = (long)textString.size();
117 i2+=sizeof(long);
118
119 //バッファが足りない場合は再確保
120 if(BufferSize<i2+(int)textString.size()+32768){
121 while( BufferSize<i2+(int)textString.size()+32768 )
122 {
123 BufferSize+=32768;
124 }
125
126 buffer=(char *)HeapReAlloc(hHeap,0,buffer,BufferSize);
127 }
128
129 // バッファ
130 memcpy( buffer+i2, textString.c_str(), textString.size() );
131 i2 += (int)textString.size();
132 }
133
134
[4]135 ////////////////////////
136 // コードと行番号の関係
137 ////////////////////////
[743]138 *(long *)(buffer+i2)=(long)sourceLines.size();
[263]139 i2+=sizeof(long);
[750]140 foreach( const SourceLine &sourceLine, sourceLines )
[263]141 {
142 *(long *)(buffer+i2) = sourceLine.GetNativeCodePos();
143 i2+=sizeof(long);
144
[637]145 *(long *)(buffer+i2) = sourceLine.GetCodeType();
[280]146 i2+=sizeof(long);
147
[637]148 *(long *)(buffer+i2) = sourceLine.GetSourceCodePosition().GetRelationalObjectModuleIndex();
[263]149 i2+=sizeof(long);
150
[637]151 *(long *)(buffer+i2) = sourceLine.GetSourceCodePosition().GetPos();
[263]152 i2+=sizeof(long);
153
154 //バッファが足りない場合は再確保
155 if(BufferSize<i2+32768){
156 BufferSize+=32768;
157 buffer=(char *)HeapReAlloc(hHeap,0,buffer,BufferSize);
158 }
[4]159 }
160
161 //グローバル実行領域のサイズ
162 extern int GlobalOpBufferSize;
163 *(long *)(buffer+i2)=GlobalOpBufferSize;
164 i2+=sizeof(long);
165
166 length=i2;
167}
168
[743]169char *DebugSection::MakeSingleStepCode(){
[4]170 char *buffer;
171 buffer=(char *)HeapAlloc(hHeap,0,SizeOf_CodeSection);
172
173 memcpy(buffer,OpBuffer,SizeOf_CodeSection);
174
[750]175 foreach( const SourceLine &sourceLine, _oldSourceLines )
[263]176 {
[4]177 if(!(
[263]178 sourceLine.IsInSystemProc()
179 || sourceLine.IsInDebugProc() ) )
180 {
[4]181 //int 3
[263]182 buffer[sourceLine.GetNativeCodePos()]=(char)0xCC;
[4]183 }
184 }
185
186 return buffer;
187}
[743]188BOOL DebugSection::__load(){
[265]189 int i2,i3;
[4]190
[536]191 compiler.ClearCompilingUserProcAndClass();
[16]192
[4]193 i2=0;
194
195 //デバッグ用ファイルのバージョンをチェック
196 if(*(long *)(buffer+i2)<MDLFILE_VER){
197 HeapDefaultFree(buffer);
198 return 0;
199 }
200 i2+=sizeof(long);
201
202 //プラットフォームのビット数をチェック
203 if(*(long *)(buffer+i2)!=PLATFORM){
204 HeapDefaultFree(buffer);
205 return 0;
206 }
207 i2+=sizeof(long);
208
[264]209 // オブジェクトモジュール
210 {
211 // サイズ
212 int size = *(long *)(buffer+i2);
213 i2 += sizeof(long);
214
215 // バッファ
[587]216 const std::string textString( (const char *)(buffer + i2), size );
[265]217 i2 += size;
[264]218
219 // テキストデータからシリアライズ
[587]220 this->objectModule.ReadString( textString );
[265]221
[636]222 compiler.SelectObjectModule( &this->objectModule );
[264]223 }
224
[636]225 // オブジェクトモジュールリストに類似したソースコードリスト
226 {
227 // サイズ
228 int size = *(long *)(buffer+i2);
229 i2 += sizeof(long);
[268]230
[636]231 // バッファ
232 const std::string textString( (const char *)(buffer + i2), size );
233 i2 += size;
234
235 // テキストデータからシリアライズ
236 this->_sourcesLinkRelationalObjectModule.ReadBinaryString( textString );
237 }
238
[4]239 //コードと行番号の関係
[268]240 int maxLineInfoNum = *(long *)(buffer+i2);
[4]241 i2+=sizeof(long);
[263]242 for(i3=0;i3<maxLineInfoNum;i3++){
[637]243 int nativeCodePos = *(long *)(buffer+i2);
[263]244 i2+=sizeof(long);
[4]245
[637]246 DWORD sourceLineType = *(DWORD *)(buffer+i2);
[263]247 i2+=sizeof(long);
[4]248
[637]249 int relationalObjectModuleIndex = *(long *)(buffer+i2);
[280]250 i2+=sizeof(long);
251
[263]252 int sourceCodePos = *(long *)(buffer+i2);
253 i2+=sizeof(long);
254
[280]255 _oldSourceLines.push_back(
256 SourceLine(
257 nativeCodePos,
[637]258 sourceLineType,
259 SourceCodePosition( relationalObjectModuleIndex, sourceCodePos )
[280]260 )
261 );
[263]262 }
263
[4]264 //グローバル実行領域のサイズ
265 GlobalOpBufferSize=*(long *)(buffer+i2);
266 i2+=sizeof(long);
267
268
269 HeapDefaultFree(buffer);
270 buffer=0;
271
272
[265]273 this->pSub_DebugSys_EndProc=GetSubHash("_DebugSys_EndProc");
274 if( this->pSub_DebugSys_EndProc == NULL )
275 {
276 MessageBox( 0, "_DebugSys_EndProcが見つからない", "ActiveBasic", MB_OK );
277 }
[4]278
279
280 SingleStepCodeBuffer=MakeSingleStepCode();
[313]281
282 //ソースコード
283 extern char *basbuf;
[636]284 basbuf = const_cast<char *>(compiler.GetObjectModule().GetSource().GetBuffer());
[4]285
286
287 /////////////////////////////
288 // ブレークポイントを適用
289 /////////////////////////////
290
[636]291 // オブジェクトモジュールリストに類似したソースコードリスト
292 extern BasicSources sourcesLinkRelationalObjectModule;
293 sourcesLinkRelationalObjectModule = this->_sourcesLinkRelationalObjectModule;
294
[743]295 BreakStepCodeBuffer=pobj_DBBreakPoint->update(OpBuffer,SizeOf_CodeSection, this->_oldSourceLines);
[4]296
297 //プロセスメモリにコピー
298 extern HANDLE hDebugProcess;
[76]299 SIZE_T accessBytes;
[4]300 WriteProcessMemory(hDebugProcess,(void *)(ULONG_PTR)(dwImageBase+dwRVA_CodeSection),
301 BreakStepCodeBuffer,
[76]302 SizeOf_CodeSection,&accessBytes);
[4]303
304
305 return 1;
306}
307
[741]308BOOL DebugSection::load(HMODULE hModule){
[4]309 if(buffer){
310 HeapDefaultFree(buffer);
311 buffer=0;
312 }
313
314
315 extern HANDLE hDebugProcess;
[76]316 SIZE_T accessBytes;
[4]317 IMAGE_DOS_HEADER ImageDosHeader;
[76]318 ReadProcessMemory(hDebugProcess,hModule,&ImageDosHeader,sizeof(IMAGE_DOS_HEADER),&accessBytes);
[4]319
320 int pe_size;
321#ifdef _AMD64_
322 IMAGE_NT_HEADERS64 pe_hdr;
323 pe_size=sizeof(IMAGE_NT_HEADERS64);
324#else
325 IMAGE_NT_HEADERS pe_hdr;
326 pe_size=sizeof(IMAGE_NT_HEADERS);
327#endif
[76]328 ReadProcessMemory(hDebugProcess,(void *)(((ULONG_PTR)hModule)+ImageDosHeader.e_lfanew),&pe_hdr,pe_size,&accessBytes);
[4]329
330 IMAGE_SECTION_HEADER *pSectionHdr;
331 pSectionHdr=(IMAGE_SECTION_HEADER *)HeapAlloc(hHeap,0,pe_hdr.FileHeader.NumberOfSections*sizeof(IMAGE_SECTION_HEADER));
332 ReadProcessMemory(hDebugProcess,
333 (void *)(((ULONG_PTR)hModule)+ImageDosHeader.e_lfanew+pe_size),
334 pSectionHdr,
335 pe_hdr.FileHeader.NumberOfSections*sizeof(IMAGE_SECTION_HEADER),
[76]336 &accessBytes);
[4]337
338 int i;
339 for(i=0;i<pe_hdr.FileHeader.NumberOfSections;i++){
340
341 //リライタブルセクション内の情報
342 if(lstrcmp((char *)pSectionHdr[i].Name,".data")==0){
343 dwRVA_RWSection=pSectionHdr[i].VirtualAddress;
344 }
345
346 //コードセクション内の情報
347 if(lstrcmp((char *)pSectionHdr[i].Name,".text")==0){
348 dwRVA_CodeSection=pSectionHdr[i].VirtualAddress;
349 SizeOf_CodeSection=pSectionHdr[i].SizeOfRawData;
350 }
351
352 //デバッグセクション内の情報
353 if(lstrcmp((char *)pSectionHdr[i].Name,".debug")==0){
354 length=pSectionHdr[i].Misc.VirtualSize;
355 buffer=(char *)HeapAlloc(hHeap,0,length+1);
356
357 ReadProcessMemory(hDebugProcess,
358 (void *)(((ULONG_PTR)hModule)+pSectionHdr[i].VirtualAddress),
359 buffer,
360 length,
[76]361 &accessBytes);
[4]362 buffer[length]=0;
363 }
364
365 }
366 HeapDefaultFree(pSectionHdr);
367
368 if(!buffer) return 0;
369
370
371 dwImageBase=(DWORD)(ULONG_PTR)hModule;
372
373
374
[191]375 if(OpBuffer) free(OpBuffer);
[188]376 OpBuffer=(char *)malloc(SizeOf_CodeSection);
[4]377
378 ReadProcessMemory(hDebugProcess,
379 (void *)(ULONG_PTR)(dwImageBase+dwRVA_CodeSection),OpBuffer,
[76]380 SizeOf_CodeSection,&accessBytes);
[4]381
382
383 return __load();
384}
385
[743]386void DebugSection::choice(){
[4]387 //イメージベース
388 extern DWORD ImageBase;
389 ImageBase=this->dwImageBase;
390
391 //リライタブルセクションのRVA
392 extern int MemPos_RWSection;
393 MemPos_RWSection=this->dwRVA_RWSection;
394
395 //コードセクションのRVAとサイズ
396 extern int MemPos_CodeSection;
397 extern int FileSize_CodeSection;
398 MemPos_CodeSection=this->dwRVA_CodeSection;
399 FileSize_CodeSection=this->SizeOf_CodeSection;
400
[265]401 // オブジェクトモジュール
[636]402 compiler.SelectObjectModule( &this->objectModule );
[265]403
[4]404 //グローバル実行領域のサイズ
405 extern int GlobalOpBufferSize;
406 GlobalOpBufferSize=this->GlobalOpBufferSize;
407
[206]408 extern const UserProc *pSub_DebugSys_EndProc;
[4]409 pSub_DebugSys_EndProc=this->pSub_DebugSys_EndProc;
410
411 //ネイティブコードバッファ
412 extern char *OpBuffer;
413 OpBuffer=this->OpBuffer;
414}
415
[743]416void DebugSection::DeleteDebugInfo(){
[4]417 //コードバッファを解放
[182]418 free(OpBuffer);
[4]419 OpBuffer=0;
420
421 HeapDefaultFree(SingleStepCodeBuffer);
422 SingleStepCodeBuffer=0;
423
424 HeapDefaultFree(BreakStepCodeBuffer);
425 BreakStepCodeBuffer=0;
426}
427
428
429
[741]430DebugSectionCollection::DebugSectionCollection()
[740]431{
[4]432}
[741]433DebugSectionCollection::~DebugSectionCollection()
[740]434{
[750]435 foreach( DebugSection *pDebugSection, debugSections )
[740]436 {
437 delete pDebugSection;
[4]438 }
[740]439 debugSections.clear();
[4]440}
441
[741]442BOOL DebugSectionCollection::add(HMODULE hModule){
443 DebugSection *pobj_d;
444 pobj_d=new DebugSection();
[4]445 if(!pobj_d->load(hModule)){
446 //デバッグ情報が存在しないとき
447 delete pobj_d;
448 return 0;
449 }
450
[740]451 debugSections.push_back( pobj_d );
[4]452
453 return 1;
454}
455
[741]456void DebugSectionCollection::del(HMODULE hModule){
[740]457 for( int i=0; i<static_cast<int>(this->debugSections.size()); i++ )
458 {
459 if( (HMODULE)(ULONG_PTR)this->debugSections[i]->dwImageBase == hModule )
460 {
461 delete debugSections[i];
[741]462 Jenga::Common::EraseVectorItem<std::vector<DebugSection *>>( debugSections, i );
[4]463 break;
464 }
465 }
466}
467
[741]468void DebugSectionCollection::choice( int index )
[740]469{
[741]470 pCurrent = debugSections[index];
471 pCurrent->choice();
[4]472}
Note: See TracBrowser for help on using the repository browser.