source: dev/trunk/abdev/BasicCompiler_Common/DebugMiddleFile.cpp@ 268

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