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

Last change on this file since 636 was 636, checked in by dai_9181, 15 years ago

libファイルを跨ったテンプレート展開に対応。

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