source: dev/branches/egtra/ab5.0/abdev/BasicCompiler_Common/DebugMiddleFile.cpp@ 807

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

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

File size: 11.1 KB
Line 
1#include "stdafx.h"
2
3#include "../BasicCompiler_Common/DebugSection.h"
4
5#ifdef _AMD64_
6#include "../compiler_x64/opcode.h"
7#else
8#include "../compiler_x86/opcode.h"
9#endif
10
11#define MDLFILE_VER 0x70000003
12
13using namespace ActiveBasic::Compiler;
14
15
16void SetLpIndex_DebugFile(char *buffer,int *p,const Type &type){
17 if(NATURAL_TYPE(type.GetBasicType())==DEF_OBJECT || NATURAL_TYPE(type.GetBasicType())==DEF_STRUCT){
18 lstrcpy(buffer+(*p),type.GetClass().GetName().c_str());
19 (*p)+=lstrlen(buffer+(*p))+1;
20 }
21 else{
22 *(LONG_PTR *)(buffer+(*p))=type.GetIndex();
23 (*p)+=sizeof(LONG_PTR);
24 }
25}
26
27
28void GetLpIndex_DebugFile(char *buffer,int *p,Type &type){
29 if(NATURAL_TYPE(type.GetBasicType())==DEF_OBJECT || NATURAL_TYPE(type.GetBasicType())==DEF_STRUCT){
30 char szClassName[VN_SIZE];
31 lstrcpy(szClassName,buffer+(*p));
32 (*p)+=lstrlen(buffer+(*p))+1;
33
34 type.SetClassPtr(
35 compiler.GetObjectModule().meta.GetClasses().FindEx( LexicalAnalyzer::FullNameToSymbol( szClassName ) )
36 );
37 }
38 else{
39 type.SetIndex( *(LONG_PTR *)(buffer+(*p)) );
40 (*p)+=sizeof(LONG_PTR);
41 }
42}
43
44
45
46DebugSection::~DebugSection(){
47 if(dwImageBase) DeleteDebugInfo();
48 if(buffer){
49 HeapDefaultFree(buffer);
50 buffer=0;
51 }
52}
53void DebugSection::make( const SourceLines &sourceLines )
54{
55 int i2,BufferSize;
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
76
77 // オブジェクトモジュール
78 {
79 // テキストデータにシリアライズ
80 std::string textString;
81 compiler.GetObjectModule().WriteString( textString );
82
83 // サイズ
84 *(long *)(buffer+i2) = (long)textString.size();
85 i2+=sizeof(long);
86
87 //バッファが足りない場合は再確保
88 if(BufferSize<i2+(int)textString.size()+32768){
89 while( BufferSize<i2+(int)textString.size()+32768 )
90 {
91 BufferSize+=32768;
92 }
93
94 buffer=(char *)HeapReAlloc(hHeap,0,buffer,BufferSize);
95 }
96
97 // バッファ
98 memcpy( buffer+i2, textString.c_str(), textString.size() );
99 i2 += (int)textString.size();
100 }
101
102 // オブジェクトモジュールリストに類似したソースコードリスト
103 {
104 // オブジェクトモジュールリストに類似したソースコードリストを作成
105 BasicSources sources;
106 foreach( const ObjectModule *pObjectModule, compiler.staticLibraries )
107 {
108 sources.push_back( pObjectModule->GetSource() );
109 }
110
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
135 ////////////////////////
136 // コードと行番号の関係
137 ////////////////////////
138 *(long *)(buffer+i2)=(long)sourceLines.size();
139 i2+=sizeof(long);
140 foreach( const SourceLine &sourceLine, sourceLines )
141 {
142 *(long *)(buffer+i2) = sourceLine.GetNativeCodePos();
143 i2+=sizeof(long);
144
145 *(long *)(buffer+i2) = sourceLine.GetCodeType();
146 i2+=sizeof(long);
147
148 *(long *)(buffer+i2) = sourceLine.GetSourceCodePosition().GetRelationalObjectModuleIndex();
149 i2+=sizeof(long);
150
151 *(long *)(buffer+i2) = sourceLine.GetSourceCodePosition().GetPos();
152 i2+=sizeof(long);
153
154 //バッファが足りない場合は再確保
155 if(BufferSize<i2+32768){
156 BufferSize+=32768;
157 buffer=(char *)HeapReAlloc(hHeap,0,buffer,BufferSize);
158 }
159 }
160
161 //グローバル実行領域のサイズ
162 extern int GlobalOpBufferSize;
163 *(long *)(buffer+i2)=GlobalOpBufferSize;
164 i2+=sizeof(long);
165
166 length=i2;
167}
168
169char *DebugSection::MakeSingleStepCode(){
170 char *buffer;
171 buffer=(char *)HeapAlloc(hHeap,0,SizeOf_CodeSection);
172
173 memcpy(buffer,OpBuffer,SizeOf_CodeSection);
174
175 foreach( const SourceLine &sourceLine, _oldSourceLines )
176 {
177 if(!(
178 sourceLine.IsInSystemProc()
179 || sourceLine.IsInDebugProc() ) )
180 {
181 //int 3
182 buffer[sourceLine.GetNativeCodePos()]=(char)0xCC;
183 }
184 }
185
186 return buffer;
187}
188BOOL DebugSection::__load(){
189 int i2,i3;
190
191 compiler.ClearCompilingUserProcAndClass();
192
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
209 // オブジェクトモジュール
210 {
211 // サイズ
212 int size = *(long *)(buffer+i2);
213 i2 += sizeof(long);
214
215 // バッファ
216 const std::string textString( (const char *)(buffer + i2), size );
217 i2 += size;
218
219 // テキストデータからシリアライズ
220 this->objectModule.ReadString( textString );
221
222 compiler.SelectObjectModule( &this->objectModule );
223 }
224
225 // オブジェクトモジュールリストに類似したソースコードリスト
226 {
227 // サイズ
228 int size = *(long *)(buffer+i2);
229 i2 += sizeof(long);
230
231 // バッファ
232 const std::string textString( (const char *)(buffer + i2), size );
233 i2 += size;
234
235 // テキストデータからシリアライズ
236 this->_sourcesLinkRelationalObjectModule.ReadBinaryString( textString );
237 }
238
239 //コードと行番号の関係
240 int maxLineInfoNum = *(long *)(buffer+i2);
241 i2+=sizeof(long);
242 for(i3=0;i3<maxLineInfoNum;i3++){
243 int nativeCodePos = *(long *)(buffer+i2);
244 i2+=sizeof(long);
245
246 DWORD sourceLineType = *(DWORD *)(buffer+i2);
247 i2+=sizeof(long);
248
249 int relationalObjectModuleIndex = *(long *)(buffer+i2);
250 i2+=sizeof(long);
251
252 int sourceCodePos = *(long *)(buffer+i2);
253 i2+=sizeof(long);
254
255 _oldSourceLines.push_back(
256 SourceLine(
257 nativeCodePos,
258 sourceLineType,
259 SourceCodePosition( relationalObjectModuleIndex, sourceCodePos )
260 )
261 );
262 }
263
264 //グローバル実行領域のサイズ
265 GlobalOpBufferSize=*(long *)(buffer+i2);
266 i2+=sizeof(long);
267
268
269 HeapDefaultFree(buffer);
270 buffer=0;
271
272
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 }
278
279
280 SingleStepCodeBuffer=MakeSingleStepCode();
281
282 //ソースコード
283 extern char *basbuf;
284 basbuf = const_cast<char *>(compiler.GetObjectModule().GetSource().GetBuffer());
285
286
287 /////////////////////////////
288 // ブレークポイントを適用
289 /////////////////////////////
290
291 // オブジェクトモジュールリストに類似したソースコードリスト
292 extern BasicSources sourcesLinkRelationalObjectModule;
293 sourcesLinkRelationalObjectModule = this->_sourcesLinkRelationalObjectModule;
294
295 BreakStepCodeBuffer=pobj_DBBreakPoint->update(OpBuffer,SizeOf_CodeSection, this->_oldSourceLines);
296
297 //プロセスメモリにコピー
298 extern HANDLE hDebugProcess;
299 SIZE_T accessBytes;
300 WriteProcessMemory(hDebugProcess,(void *)(ULONG_PTR)(dwImageBase+dwRVA_CodeSection),
301 BreakStepCodeBuffer,
302 SizeOf_CodeSection,&accessBytes);
303
304
305 return 1;
306}
307
308BOOL DebugSection::load(HMODULE hModule){
309 if(buffer){
310 HeapDefaultFree(buffer);
311 buffer=0;
312 }
313
314
315 extern HANDLE hDebugProcess;
316 SIZE_T accessBytes;
317 IMAGE_DOS_HEADER ImageDosHeader;
318 ReadProcessMemory(hDebugProcess,hModule,&ImageDosHeader,sizeof(IMAGE_DOS_HEADER),&accessBytes);
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
328 ReadProcessMemory(hDebugProcess,(void *)(((ULONG_PTR)hModule)+ImageDosHeader.e_lfanew),&pe_hdr,pe_size,&accessBytes);
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),
336 &accessBytes);
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,
361 &accessBytes);
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
375 if(OpBuffer) free(OpBuffer);
376 OpBuffer=(char *)malloc(SizeOf_CodeSection);
377
378 ReadProcessMemory(hDebugProcess,
379 (void *)(ULONG_PTR)(dwImageBase+dwRVA_CodeSection),OpBuffer,
380 SizeOf_CodeSection,&accessBytes);
381
382
383 return __load();
384}
385
386void DebugSection::choice(){
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
401 // オブジェクトモジュール
402 compiler.SelectObjectModule( &this->objectModule );
403
404 //グローバル実行領域のサイズ
405 extern int GlobalOpBufferSize;
406 GlobalOpBufferSize=this->GlobalOpBufferSize;
407
408 extern const UserProc *pSub_DebugSys_EndProc;
409 pSub_DebugSys_EndProc=this->pSub_DebugSys_EndProc;
410
411 //ネイティブコードバッファ
412 extern char *OpBuffer;
413 OpBuffer=this->OpBuffer;
414}
415
416void DebugSection::DeleteDebugInfo(){
417 //コードバッファを解放
418 free(OpBuffer);
419 OpBuffer=0;
420
421 HeapDefaultFree(SingleStepCodeBuffer);
422 SingleStepCodeBuffer=0;
423
424 HeapDefaultFree(BreakStepCodeBuffer);
425 BreakStepCodeBuffer=0;
426}
427
428
429
430DebugSectionCollection::DebugSectionCollection()
431{
432}
433DebugSectionCollection::~DebugSectionCollection()
434{
435 foreach( DebugSection *pDebugSection, debugSections )
436 {
437 delete pDebugSection;
438 }
439 debugSections.clear();
440}
441
442BOOL DebugSectionCollection::add(HMODULE hModule){
443 DebugSection *pobj_d;
444 pobj_d=new DebugSection();
445 if(!pobj_d->load(hModule)){
446 //デバッグ情報が存在しないとき
447 delete pobj_d;
448 return 0;
449 }
450
451 debugSections.push_back( pobj_d );
452
453 return 1;
454}
455
456void DebugSectionCollection::del(HMODULE hModule){
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];
462 Jenga::Common::EraseVectorItem<std::vector<DebugSection *>>( debugSections, i );
463 break;
464 }
465 }
466}
467
468void DebugSectionCollection::choice( int index )
469{
470 pCurrent = debugSections[index];
471 pCurrent->choice();
472}
Note: See TracBrowser for help on using the repository browser.