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

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

ObjectModuleに関連するクラス一式をab_commonプロジェクトに移動した。

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