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

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

リンカの依存関係解決モジュールを製作中

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