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

Last change on this file since 741 was 741, checked in by dai, 16 years ago

デバッグセクション情報周りをリファクタリング

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