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
RevLine 
[206]1#include "stdafx.h"
2
[182]3#include <jenga/include/smoothie/Smoothie.h>
4
[193]5#include <Compiler.h>
[206]6#include <Class.h>
7#include <Variable.h>
[182]8
[4]9#include "../BasicCompiler_Common/common.h"
[206]10#include "../BasicCompiler_Common/DebugSection.h"
[4]11
12#ifdef _AMD64_
13#include "../BasicCompiler64/opcode.h"
14#else
[5]15#include "../BasicCompiler32/opcode.h"
[4]16#endif
17
18#define MDLFILE_VER 0x70000003
19
20
[75]21void SetLpIndex_DebugFile(char *buffer,int *p,const Type &type){
22 if(NATURAL_TYPE(type.GetBasicType())==DEF_OBJECT || NATURAL_TYPE(type.GetBasicType())==DEF_STRUCT){
[131]23 lstrcpy(buffer+(*p),type.GetClass().GetName().c_str());
[4]24 (*p)+=lstrlen(buffer+(*p))+1;
25 }
26 else{
[75]27 *(LONG_PTR *)(buffer+(*p))=type.GetIndex();
[4]28 (*p)+=sizeof(LONG_PTR);
29 }
30}
31
32
[75]33void GetLpIndex_DebugFile(char *buffer,int *p,Type &type){
34 if(NATURAL_TYPE(type.GetBasicType())==DEF_OBJECT || NATURAL_TYPE(type.GetBasicType())==DEF_STRUCT){
[4]35 char szClassName[VN_SIZE];
36 lstrcpy(szClassName,buffer+(*p));
37 (*p)+=lstrlen(buffer+(*p))+1;
38
[265]39 type.SetClassPtr( compiler.GetObjectModule().meta.GetClasses().Find(szClassName) );
[4]40 }
41 else{
[75]42 type.SetIndex( *(LONG_PTR *)(buffer+(*p)) );
[4]43 (*p)+=sizeof(LONG_PTR);
44 }
45}
46
47
48
49CDebugSection::~CDebugSection(){
[265]50 if(dwImageBase) DeleteDebugInfo();
[4]51 if(buffer){
52 HeapDefaultFree(buffer);
53 buffer=0;
54 }
55}
56void CDebugSection::make(void){
[206]57 int i2,i3,BufferSize;
[4]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
[264]78
79 // オブジェクトモジュール
80 {
81 // テキストデータにシリアライズ
82 std::string textString;
[265]83 compiler.GetObjectModule().WriteTextString( textString );
[264]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
[4]105 //インクルード情報
[265]106 extern INCLUDEFILEINFO IncludeFileInfo;
[4]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;
[265]117
118 //バッファが足りない場合は再確保
119 if(BufferSize<i2+32768){
120 BufferSize+=32768;
121 buffer=(char *)HeapReAlloc(hHeap,0,buffer,BufferSize);
122 }
[4]123 }
124
125 //ソースコード
[265]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 }
[4]138 lstrcpy(buffer+i2,basbuf);
[265]139 i2+=lstrlen( buffer + i2 )+1;
[4]140
141
142 ////////////////////////
143 // コードと行番号の関係
144 ////////////////////////
[263]145 extern SourceLines oldSourceLines;
[4]146
[263]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 }
[4]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
[265]184 BOOST_FOREACH( const SourceLine &sourceLine, _oldSourceLines )
[263]185 {
[4]186 if(!(
[263]187 sourceLine.IsInSystemProc()
188 || sourceLine.IsInDebugProc() ) )
189 {
[4]190 //int 3
[263]191 buffer[sourceLine.GetNativeCodePos()]=(char)0xCC;
[4]192 }
193 }
194
195 return buffer;
196}
197BOOL CDebugSection::__load(void){
[265]198 int i2,i3;
[4]199
[206]200 compiler.pCompilingClass = NULL;
[16]201
[4]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
[264]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 );
[265]226 i2 += size;
[264]227
228 // テキストデータからシリアライズ
229 this->objectModule.ReadTextString( textString );
[265]230
231 compiler.SelectObjectModule( this->objectModule );
[264]232 }
233
[4]234 //インクルード情報
[265]235 _IncludeFileInfo.FilesNum=*(long *)(buffer+i2);
[4]236 i2+=sizeof(long);
[265]237 _IncludeFileInfo.ppFileNames=(char **)malloc(_IncludeFileInfo.FilesNum*sizeof(char *));
238 for(i3=0;i3<_IncludeFileInfo.FilesNum;i3++){
[4]239 if(buffer[i2]=='\0') break;
[265]240 _IncludeFileInfo.ppFileNames[i3]=(char *)malloc(lstrlen(buffer+i2)+1);
241 lstrcpy(_IncludeFileInfo.ppFileNames[i3],buffer+i2);
[4]242 i2+=lstrlen(buffer+i2)+1;
243 }
244 for(i2++,i3=0;;i2++,i3++){
[265]245 _IncludeFileInfo.LineOfFile[i3]=(long)buffer[i2];
246 if(_IncludeFileInfo.LineOfFile[i3]==-1) break;
[4]247 }
248
249 //ソースコード
250 i2++;
[88]251 source.SetBuffer( buffer + i2 );
[15]252 i2+=lstrlen(buffer+i2)+1;
[4]253
254 //コードと行番号の関係
[263]255 int maxLineInfoNum;
256 maxLineInfoNum=*(long *)(buffer+i2);
[4]257 i2+=sizeof(long);
[263]258 for(i3=0;i3<maxLineInfoNum;i3++){
259 int lineNum = *(long *)(buffer+i2);
260 i2+=sizeof(long);
[4]261
[263]262 int nativeCodePos = *(long *)(buffer+i2);
263 i2+=sizeof(long);
[4]264
[263]265 int sourceCodePos = *(long *)(buffer+i2);
266 i2+=sizeof(long);
267
268 DWORD sourceLineType = *(DWORD *)(buffer+i2);
269 i2+=sizeof(long);
270
[265]271 _oldSourceLines.push_back( SourceLine( lineNum, nativeCodePos, sourceCodePos, sourceLineType ) );
[263]272 }
273
[4]274 //グローバル実行領域のサイズ
275 GlobalOpBufferSize=*(long *)(buffer+i2);
276 i2+=sizeof(long);
277
278
279 HeapDefaultFree(buffer);
280 buffer=0;
281
282
[265]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 }
[4]288
289
290 SingleStepCodeBuffer=MakeSingleStepCode();
291
292
293 /////////////////////////////
294 // ブレークポイントを適用
295 /////////////////////////////
296
297 //インクルード情報
298 extern INCLUDEFILEINFO IncludeFileInfo;
[265]299 IncludeFileInfo=this->_IncludeFileInfo;
[4]300
301 //コードと行番号の関係
[263]302 extern SourceLines oldSourceLines;
[265]303 oldSourceLines = this->_oldSourceLines;
[4]304
305 BreakStepCodeBuffer=pobj_DBBreakPoint->update(OpBuffer,SizeOf_CodeSection);
306
307 //プロセスメモリにコピー
308 extern HANDLE hDebugProcess;
[76]309 SIZE_T accessBytes;
[4]310 WriteProcessMemory(hDebugProcess,(void *)(ULONG_PTR)(dwImageBase+dwRVA_CodeSection),
311 BreakStepCodeBuffer,
[76]312 SizeOf_CodeSection,&accessBytes);
[4]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;
[76]326 SIZE_T accessBytes;
[4]327 IMAGE_DOS_HEADER ImageDosHeader;
[76]328 ReadProcessMemory(hDebugProcess,hModule,&ImageDosHeader,sizeof(IMAGE_DOS_HEADER),&accessBytes);
[4]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
[76]338 ReadProcessMemory(hDebugProcess,(void *)(((ULONG_PTR)hModule)+ImageDosHeader.e_lfanew),&pe_hdr,pe_size,&accessBytes);
[4]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),
[76]346 &accessBytes);
[4]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,
[76]371 &accessBytes);
[4]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
[191]385 if(OpBuffer) free(OpBuffer);
[188]386 OpBuffer=(char *)malloc(SizeOf_CodeSection);
[4]387
388 ReadProcessMemory(hDebugProcess,
389 (void *)(ULONG_PTR)(dwImageBase+dwRVA_CodeSection),OpBuffer,
[76]390 SizeOf_CodeSection,&accessBytes);
[4]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
[265]411 // オブジェクトモジュール
412 compiler.SelectObjectModule( this->objectModule );
413
[4]414 //インクルード情報
415 extern INCLUDEFILEINFO IncludeFileInfo;
[265]416 IncludeFileInfo=this->_IncludeFileInfo;
[4]417
418 //ソースコード
[88]419 Smoothie::Lexical::source = source;
[4]420
421 //コードと行番号の関係
[263]422 extern SourceLines oldSourceLines;
[265]423 oldSourceLines = this->_oldSourceLines;
[4]424
425 //グローバル実行領域のサイズ
426 extern int GlobalOpBufferSize;
427 GlobalOpBufferSize=this->GlobalOpBufferSize;
428
[206]429 extern const UserProc *pSub_DebugSys_EndProc;
[4]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 //インクルード情報を解放
[265]441 for(i2=0;i2<_IncludeFileInfo.FilesNum;i2++)
[191]442 {
[265]443 free(_IncludeFileInfo.ppFileNames[i2]);
[191]444 }
[265]445 free(_IncludeFileInfo.ppFileNames);
[4]446
447 //コードバッファを解放
[182]448 free(OpBuffer);
[4]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.