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

Last change on this file since 266 was 266, checked in by dai_9181, 17 years ago

BasicSourceのシリアライズがうまくいっていない

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