source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/DebugMiddleFile.cpp@ 598

Last change on this file since 598 was 598, checked in by dai_9181, 16 years ago

SplitMemberNameの依存関係を排除。

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