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

Last change on this file since 636 was 636, checked in by dai_9181, 16 years ago

libファイルを跨ったテンプレート展開に対応。

File size: 11.5 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
46CDebugSection::~CDebugSection(){
47 if(dwImageBase) DeleteDebugInfo();
48 if(buffer){
49 HeapDefaultFree(buffer);
50 buffer=0;
51 }
52}
53void CDebugSection::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.GetLineNum();
144 i2+=sizeof(long);
145
146 *(long *)(buffer+i2) = sourceLine.GetNativeCodePos();
147 i2+=sizeof(long);
148
149 *(long *)(buffer+i2) = sourceLine.GetRelationalObjectModuleIndex();
150 i2+=sizeof(long);
151
152 *(long *)(buffer+i2) = sourceLine.GetSourceCodePos();
153 i2+=sizeof(long);
154
155 *(long *)(buffer+i2) = sourceLine.GetCodeType();
156 i2+=sizeof(long);
157
158 //バッファが足りない場合は再確保
159 if(BufferSize<i2+32768){
160 BufferSize+=32768;
161 buffer=(char *)HeapReAlloc(hHeap,0,buffer,BufferSize);
162 }
163 }
164
165 //グローバル実行領域のサイズ
166 extern int GlobalOpBufferSize;
167 *(long *)(buffer+i2)=GlobalOpBufferSize;
168 i2+=sizeof(long);
169
170 length=i2;
171}
172
173char *CDebugSection::MakeSingleStepCode(void){
174 char *buffer;
175 buffer=(char *)HeapAlloc(hHeap,0,SizeOf_CodeSection);
176
177 memcpy(buffer,OpBuffer,SizeOf_CodeSection);
178
179 BOOST_FOREACH( const SourceLine &sourceLine, _oldSourceLines )
180 {
181 if(!(
182 sourceLine.IsInSystemProc()
183 || sourceLine.IsInDebugProc() ) )
184 {
185 //int 3
186 buffer[sourceLine.GetNativeCodePos()]=(char)0xCC;
187 }
188 }
189
190 return buffer;
191}
192BOOL CDebugSection::__load(void){
193 int i2,i3;
194
195 compiler.ClearCompilingUserProcAndClass();
196
197 i2=0;
198
199 //デバッグ用ファイルのバージョンをチェック
200 if(*(long *)(buffer+i2)<MDLFILE_VER){
201 HeapDefaultFree(buffer);
202 return 0;
203 }
204 i2+=sizeof(long);
205
206 //プラットフォームのビット数をチェック
207 if(*(long *)(buffer+i2)!=PLATFORM){
208 HeapDefaultFree(buffer);
209 return 0;
210 }
211 i2+=sizeof(long);
212
213 // オブジェクトモジュール
214 {
215 // サイズ
216 int size = *(long *)(buffer+i2);
217 i2 += sizeof(long);
218
219 // バッファ
220 const std::string textString( (const char *)(buffer + i2), size );
221 i2 += size;
222
223 // テキストデータからシリアライズ
224 this->objectModule.ReadString( textString );
225
226 compiler.SelectObjectModule( &this->objectModule );
227 }
228
229 // オブジェクトモジュールリストに類似したソースコードリスト
230 {
231 // サイズ
232 int size = *(long *)(buffer+i2);
233 i2 += sizeof(long);
234
235 // バッファ
236 const std::string textString( (const char *)(buffer + i2), size );
237 i2 += size;
238
239 // テキストデータからシリアライズ
240 this->_sourcesLinkRelationalObjectModule.ReadBinaryString( textString );
241 }
242
243 //コードと行番号の関係
244 int maxLineInfoNum = *(long *)(buffer+i2);
245 i2+=sizeof(long);
246 for(i3=0;i3<maxLineInfoNum;i3++){
247 int lineNum = *(long *)(buffer+i2);
248 i2+=sizeof(long);
249
250 int nativeCodePos = *(long *)(buffer+i2);
251 i2+=sizeof(long);
252
253 int sourceIndex = *(long *)(buffer+i2);
254 i2+=sizeof(long);
255
256 int sourceCodePos = *(long *)(buffer+i2);
257 i2+=sizeof(long);
258
259 DWORD sourceLineType = *(DWORD *)(buffer+i2);
260 i2+=sizeof(long);
261
262 _oldSourceLines.push_back(
263 SourceLine(
264 lineNum,
265 nativeCodePos,
266 sourceIndex,
267 sourceCodePos,
268 sourceLineType
269 )
270 );
271 }
272
273 //グローバル実行領域のサイズ
274 GlobalOpBufferSize=*(long *)(buffer+i2);
275 i2+=sizeof(long);
276
277
278 HeapDefaultFree(buffer);
279 buffer=0;
280
281
282 this->pSub_DebugSys_EndProc=GetSubHash("_DebugSys_EndProc");
283 if( this->pSub_DebugSys_EndProc == NULL )
284 {
285 MessageBox( 0, "_DebugSys_EndProcが見つからない", "ActiveBasic", MB_OK );
286 }
287
288
289 SingleStepCodeBuffer=MakeSingleStepCode();
290
291 //ソースコード
292 extern char *basbuf;
293 basbuf = const_cast<char *>(compiler.GetObjectModule().GetSource().GetBuffer());
294
295
296 /////////////////////////////
297 // ブレークポイントを適用
298 /////////////////////////////
299
300 // オブジェクトモジュールリストに類似したソースコードリスト
301 extern BasicSources sourcesLinkRelationalObjectModule;
302 sourcesLinkRelationalObjectModule = this->_sourcesLinkRelationalObjectModule;
303
304 //コードと行番号の関係
305 extern SourceLines oldSourceLines;
306 oldSourceLines = this->_oldSourceLines;
307
308 BreakStepCodeBuffer=pobj_DBBreakPoint->update(OpBuffer,SizeOf_CodeSection);
309
310 //プロセスメモリにコピー
311 extern HANDLE hDebugProcess;
312 SIZE_T accessBytes;
313 WriteProcessMemory(hDebugProcess,(void *)(ULONG_PTR)(dwImageBase+dwRVA_CodeSection),
314 BreakStepCodeBuffer,
315 SizeOf_CodeSection,&accessBytes);
316
317
318 return 1;
319}
320
321BOOL CDebugSection::load(HMODULE hModule){
322 if(buffer){
323 HeapDefaultFree(buffer);
324 buffer=0;
325 }
326
327
328 extern HANDLE hDebugProcess;
329 SIZE_T accessBytes;
330 IMAGE_DOS_HEADER ImageDosHeader;
331 ReadProcessMemory(hDebugProcess,hModule,&ImageDosHeader,sizeof(IMAGE_DOS_HEADER),&accessBytes);
332
333 int pe_size;
334#ifdef _AMD64_
335 IMAGE_NT_HEADERS64 pe_hdr;
336 pe_size=sizeof(IMAGE_NT_HEADERS64);
337#else
338 IMAGE_NT_HEADERS pe_hdr;
339 pe_size=sizeof(IMAGE_NT_HEADERS);
340#endif
341 ReadProcessMemory(hDebugProcess,(void *)(((ULONG_PTR)hModule)+ImageDosHeader.e_lfanew),&pe_hdr,pe_size,&accessBytes);
342
343 IMAGE_SECTION_HEADER *pSectionHdr;
344 pSectionHdr=(IMAGE_SECTION_HEADER *)HeapAlloc(hHeap,0,pe_hdr.FileHeader.NumberOfSections*sizeof(IMAGE_SECTION_HEADER));
345 ReadProcessMemory(hDebugProcess,
346 (void *)(((ULONG_PTR)hModule)+ImageDosHeader.e_lfanew+pe_size),
347 pSectionHdr,
348 pe_hdr.FileHeader.NumberOfSections*sizeof(IMAGE_SECTION_HEADER),
349 &accessBytes);
350
351 int i;
352 for(i=0;i<pe_hdr.FileHeader.NumberOfSections;i++){
353
354 //リライタブルセクション内の情報
355 if(lstrcmp((char *)pSectionHdr[i].Name,".data")==0){
356 dwRVA_RWSection=pSectionHdr[i].VirtualAddress;
357 }
358
359 //コードセクション内の情報
360 if(lstrcmp((char *)pSectionHdr[i].Name,".text")==0){
361 dwRVA_CodeSection=pSectionHdr[i].VirtualAddress;
362 SizeOf_CodeSection=pSectionHdr[i].SizeOfRawData;
363 }
364
365 //デバッグセクション内の情報
366 if(lstrcmp((char *)pSectionHdr[i].Name,".debug")==0){
367 length=pSectionHdr[i].Misc.VirtualSize;
368 buffer=(char *)HeapAlloc(hHeap,0,length+1);
369
370 ReadProcessMemory(hDebugProcess,
371 (void *)(((ULONG_PTR)hModule)+pSectionHdr[i].VirtualAddress),
372 buffer,
373 length,
374 &accessBytes);
375 buffer[length]=0;
376 }
377
378 }
379 HeapDefaultFree(pSectionHdr);
380
381 if(!buffer) return 0;
382
383
384 dwImageBase=(DWORD)(ULONG_PTR)hModule;
385
386
387
388 if(OpBuffer) free(OpBuffer);
389 OpBuffer=(char *)malloc(SizeOf_CodeSection);
390
391 ReadProcessMemory(hDebugProcess,
392 (void *)(ULONG_PTR)(dwImageBase+dwRVA_CodeSection),OpBuffer,
393 SizeOf_CodeSection,&accessBytes);
394
395
396 return __load();
397}
398
399void CDebugSection::choice(void){
400 //イメージベース
401 extern DWORD ImageBase;
402 ImageBase=this->dwImageBase;
403
404 //リライタブルセクションのRVA
405 extern int MemPos_RWSection;
406 MemPos_RWSection=this->dwRVA_RWSection;
407
408 //コードセクションのRVAとサイズ
409 extern int MemPos_CodeSection;
410 extern int FileSize_CodeSection;
411 MemPos_CodeSection=this->dwRVA_CodeSection;
412 FileSize_CodeSection=this->SizeOf_CodeSection;
413
414 // オブジェクトモジュール
415 compiler.SelectObjectModule( &this->objectModule );
416
417 //コードと行番号の関係
418 extern SourceLines oldSourceLines;
419 oldSourceLines = this->_oldSourceLines;
420
421 //グローバル実行領域のサイズ
422 extern int GlobalOpBufferSize;
423 GlobalOpBufferSize=this->GlobalOpBufferSize;
424
425 extern const UserProc *pSub_DebugSys_EndProc;
426 pSub_DebugSys_EndProc=this->pSub_DebugSys_EndProc;
427
428 //ネイティブコードバッファ
429 extern char *OpBuffer;
430 OpBuffer=this->OpBuffer;
431}
432
433void CDebugSection::DeleteDebugInfo(void){
434 //コードバッファを解放
435 free(OpBuffer);
436 OpBuffer=0;
437
438 HeapDefaultFree(SingleStepCodeBuffer);
439 SingleStepCodeBuffer=0;
440
441 HeapDefaultFree(BreakStepCodeBuffer);
442 BreakStepCodeBuffer=0;
443}
444
445
446
447CDBDebugSection::CDBDebugSection(){
448 ppobj_ds=(CDebugSection **)HeapAlloc(hHeap,0,1);
449 num=0;
450}
451CDBDebugSection::~CDBDebugSection(){
452 int i;
453 for(i=0;i<num;i++){
454 delete ppobj_ds[i];
455 }
456 HeapDefaultFree(ppobj_ds);
457}
458
459BOOL CDBDebugSection::add(HMODULE hModule){
460 CDebugSection *pobj_d;
461 pobj_d=new CDebugSection();
462 if(!pobj_d->load(hModule)){
463 //デバッグ情報が存在しないとき
464 delete pobj_d;
465 return 0;
466 }
467
468 ppobj_ds=(CDebugSection **)HeapReAlloc(hHeap,0,ppobj_ds,(num+1)*sizeof(CDebugSection *));
469 ppobj_ds[num]=pobj_d;
470 num++;
471
472 return 1;
473}
474
475void CDBDebugSection::del(HMODULE hModule){
476 int i;
477 for(i=0;i<num;i++){
478 if((HMODULE)(ULONG_PTR)ppobj_ds[i]->dwImageBase==hModule){
479 delete ppobj_ds[i];
480
481 num--;
482 for(;i<num;i++){
483 ppobj_ds[i]=ppobj_ds[i+1];
484 }
485 break;
486 }
487 }
488}
489
490void CDBDebugSection::choice(int index){
491 pobj_now=ppobj_ds[index];
492 pobj_now->choice();
493}
494
495
496
497CDBDebugSection *pobj_DBDebugSection;
Note: See TracBrowser for help on using the repository browser.