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

Last change on this file since 265 was 265, checked in by dai_9181, 17 years ago
File size: 11.8 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) = 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 += textString.size();
102 }
103
104
105 //インクルード情報
106 extern INCLUDEFILEINFO IncludeFileInfo;
107 *(long *)(buffer+i2)=IncludeFileInfo.FilesNum;
108 i2+=sizeof(long);
109 for(i3=0;i3<IncludeFileInfo.FilesNum;i3++){
110 lstrcpy(buffer+i2,IncludeFileInfo.ppFileNames[i3]);
111 i2+=lstrlen(buffer+i2)+1;
112 }
113 buffer[i2++]=0;
114 for(i3=0;;i3++){
115 buffer[i2++]=(char)IncludeFileInfo.LineOfFile[i3];
116 if(IncludeFileInfo.LineOfFile[i3]==-1) break;
117
118 //バッファが足りない場合は再確保
119 if(BufferSize<i2+32768){
120 BufferSize+=32768;
121 buffer=(char *)HeapReAlloc(hHeap,0,buffer,BufferSize);
122 }
123 }
124
125 //ソースコード
126 {
127 //バッファが足りない場合は再確保
128 int bufferLen = lstrlen( basbuf );
129 if(BufferSize<i2+(int)bufferLen+32768){
130 while( BufferSize<i2+(int)bufferLen+32768 )
131 {
132 BufferSize+=32768;
133 }
134
135 buffer=(char *)HeapReAlloc(hHeap,0,buffer,BufferSize);
136 }
137 }
138 lstrcpy(buffer+i2,basbuf);
139 i2+=lstrlen( buffer + i2 )+1;
140
141
142 ////////////////////////
143 // コードと行番号の関係
144 ////////////////////////
145 extern SourceLines oldSourceLines;
146
147 *(long *)(buffer+i2)=(long)oldSourceLines.size();
148 i2+=sizeof(long);
149 BOOST_FOREACH( const SourceLine &sourceLine, oldSourceLines )
150 {
151 *(long *)(buffer+i2) = sourceLine.GetLineNum();
152 i2+=sizeof(long);
153
154 *(long *)(buffer+i2) = sourceLine.GetNativeCodePos();
155 i2+=sizeof(long);
156
157 *(long *)(buffer+i2) = sourceLine.GetSourceCodePos();
158 i2+=sizeof(long);
159
160 *(long *)(buffer+i2) = sourceLine.GetCodeType();
161 i2+=sizeof(long);
162
163 //バッファが足りない場合は再確保
164 if(BufferSize<i2+32768){
165 BufferSize+=32768;
166 buffer=(char *)HeapReAlloc(hHeap,0,buffer,BufferSize);
167 }
168 }
169
170 //グローバル実行領域のサイズ
171 extern int GlobalOpBufferSize;
172 *(long *)(buffer+i2)=GlobalOpBufferSize;
173 i2+=sizeof(long);
174
175 length=i2;
176}
177
178char *CDebugSection::MakeSingleStepCode(void){
179 char *buffer;
180 buffer=(char *)HeapAlloc(hHeap,0,SizeOf_CodeSection);
181
182 memcpy(buffer,OpBuffer,SizeOf_CodeSection);
183
184 BOOST_FOREACH( const SourceLine &sourceLine, _oldSourceLines )
185 {
186 if(!(
187 sourceLine.IsInSystemProc()
188 || sourceLine.IsInDebugProc() ) )
189 {
190 //int 3
191 buffer[sourceLine.GetNativeCodePos()]=(char)0xCC;
192 }
193 }
194
195 return buffer;
196}
197BOOL CDebugSection::__load(void){
198 int i2,i3;
199
200 compiler.pCompilingClass = NULL;
201
202 i2=0;
203
204 //デバッグ用ファイルのバージョンをチェック
205 if(*(long *)(buffer+i2)<MDLFILE_VER){
206 HeapDefaultFree(buffer);
207 return 0;
208 }
209 i2+=sizeof(long);
210
211 //プラットフォームのビット数をチェック
212 if(*(long *)(buffer+i2)!=PLATFORM){
213 HeapDefaultFree(buffer);
214 return 0;
215 }
216 i2+=sizeof(long);
217
218 // オブジェクトモジュール
219 {
220 // サイズ
221 int size = *(long *)(buffer+i2);
222 i2 += sizeof(long);
223
224 // バッファ
225 const std::string textString( (const char *)(buffer + i2), size );
226 i2 += size;
227
228 // テキストデータからシリアライズ
229 this->objectModule.ReadTextString( textString );
230
231 compiler.SelectObjectModule( this->objectModule );
232 }
233
234 //インクルード情報
235 _IncludeFileInfo.FilesNum=*(long *)(buffer+i2);
236 i2+=sizeof(long);
237 _IncludeFileInfo.ppFileNames=(char **)malloc(_IncludeFileInfo.FilesNum*sizeof(char *));
238 for(i3=0;i3<_IncludeFileInfo.FilesNum;i3++){
239 if(buffer[i2]=='\0') break;
240 _IncludeFileInfo.ppFileNames[i3]=(char *)malloc(lstrlen(buffer+i2)+1);
241 lstrcpy(_IncludeFileInfo.ppFileNames[i3],buffer+i2);
242 i2+=lstrlen(buffer+i2)+1;
243 }
244 for(i2++,i3=0;;i2++,i3++){
245 _IncludeFileInfo.LineOfFile[i3]=(long)buffer[i2];
246 if(_IncludeFileInfo.LineOfFile[i3]==-1) break;
247 }
248
249 //ソースコード
250 i2++;
251 source.SetBuffer( buffer + i2 );
252 i2+=lstrlen(buffer+i2)+1;
253
254 //コードと行番号の関係
255 int maxLineInfoNum;
256 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 Smoothie::Lexical::source = source;
420
421 //コードと行番号の関係
422 extern SourceLines oldSourceLines;
423 oldSourceLines = this->_oldSourceLines;
424
425 //グローバル実行領域のサイズ
426 extern int GlobalOpBufferSize;
427 GlobalOpBufferSize=this->GlobalOpBufferSize;
428
429 extern const UserProc *pSub_DebugSys_EndProc;
430 pSub_DebugSys_EndProc=this->pSub_DebugSys_EndProc;
431
432 //ネイティブコードバッファ
433 extern char *OpBuffer;
434 OpBuffer=this->OpBuffer;
435}
436
437void CDebugSection::DeleteDebugInfo(void){
438 int i2;
439
440 //インクルード情報を解放
441 for(i2=0;i2<_IncludeFileInfo.FilesNum;i2++)
442 {
443 free(_IncludeFileInfo.ppFileNames[i2]);
444 }
445 free(_IncludeFileInfo.ppFileNames);
446
447 //コードバッファを解放
448 free(OpBuffer);
449 OpBuffer=0;
450
451 HeapDefaultFree(SingleStepCodeBuffer);
452 SingleStepCodeBuffer=0;
453
454 HeapDefaultFree(BreakStepCodeBuffer);
455 BreakStepCodeBuffer=0;
456}
457
458
459
460CDBDebugSection::CDBDebugSection(){
461 ppobj_ds=(CDebugSection **)HeapAlloc(hHeap,0,1);
462 num=0;
463}
464CDBDebugSection::~CDBDebugSection(){
465 int i;
466 for(i=0;i<num;i++){
467 delete ppobj_ds[i];
468 }
469 HeapDefaultFree(ppobj_ds);
470}
471
472BOOL CDBDebugSection::add(HMODULE hModule){
473 CDebugSection *pobj_d;
474 pobj_d=new CDebugSection();
475 if(!pobj_d->load(hModule)){
476 //デバッグ情報が存在しないとき
477 delete pobj_d;
478 return 0;
479 }
480
481 ppobj_ds=(CDebugSection **)HeapReAlloc(hHeap,0,ppobj_ds,(num+1)*sizeof(CDebugSection *));
482 ppobj_ds[num]=pobj_d;
483 num++;
484
485 return 1;
486}
487
488void CDBDebugSection::del(HMODULE hModule){
489 int i;
490 for(i=0;i<num;i++){
491 if((HMODULE)(ULONG_PTR)ppobj_ds[i]->dwImageBase==hModule){
492 delete ppobj_ds[i];
493
494 num--;
495 for(;i<num;i++){
496 ppobj_ds[i]=ppobj_ds[i+1];
497 }
498 break;
499 }
500 }
501}
502
503void CDBDebugSection::choice(int index){
504 pobj_now=ppobj_ds[index];
505 pobj_now->choice();
506}
507
508
509
510CDBDebugSection *pobj_DBDebugSection;
Note: See TracBrowser for help on using the repository browser.