source: dev/branches/x64_compiler_on_32/abdev/BasicCompiler_Common/DebugMiddleFile.cpp@ 759

Last change on this file since 759 was 759, checked in by イグトランス (egtra), 16 years ago

マクロBUILD_X64_COMPILERの導入

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