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

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

ステップ実行時の不正終了を回避

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