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

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

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

File size: 10.0 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
101
[4]102 ////////////////////////
103 // コードと行番号の関係
104 ////////////////////////
[263]105 extern SourceLines oldSourceLines;
[4]106
[263]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
[280]117 *(long *)(buffer+i2) = sourceLine.GetSourceIndex();
118 i2+=sizeof(long);
119
[263]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 }
[4]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
[265]147 BOOST_FOREACH( const SourceLine &sourceLine, _oldSourceLines )
[263]148 {
[4]149 if(!(
[263]150 sourceLine.IsInSystemProc()
151 || sourceLine.IsInDebugProc() ) )
152 {
[4]153 //int 3
[263]154 buffer[sourceLine.GetNativeCodePos()]=(char)0xCC;
[4]155 }
156 }
157
158 return buffer;
159}
160BOOL CDebugSection::__load(void){
[265]161 int i2,i3;
[4]162
[536]163 compiler.ClearCompilingUserProcAndClass();
[16]164
[4]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
[264]181 // オブジェクトモジュール
182 {
183 // サイズ
184 int size = *(long *)(buffer+i2);
185 i2 += sizeof(long);
186
187 // バッファ
[587]188 const std::string textString( (const char *)(buffer + i2), size );
[265]189 i2 += size;
[264]190
191 // テキストデータからシリアライズ
[587]192 this->objectModule.ReadString( textString );
[265]193
194 compiler.SelectObjectModule( this->objectModule );
[264]195 }
196
[268]197
[4]198 //コードと行番号の関係
[268]199 int maxLineInfoNum = *(long *)(buffer+i2);
[4]200 i2+=sizeof(long);
[263]201 for(i3=0;i3<maxLineInfoNum;i3++){
202 int lineNum = *(long *)(buffer+i2);
203 i2+=sizeof(long);
[4]204
[263]205 int nativeCodePos = *(long *)(buffer+i2);
206 i2+=sizeof(long);
[4]207
[280]208 int sourceIndex = *(long *)(buffer+i2);
209 i2+=sizeof(long);
210
[263]211 int sourceCodePos = *(long *)(buffer+i2);
212 i2+=sizeof(long);
213
214 DWORD sourceLineType = *(DWORD *)(buffer+i2);
215 i2+=sizeof(long);
216
[280]217 _oldSourceLines.push_back(
218 SourceLine(
219 lineNum,
220 nativeCodePos,
221 sourceIndex,
222 sourceCodePos,
223 sourceLineType
224 )
225 );
[263]226 }
227
[4]228 //グローバル実行領域のサイズ
229 GlobalOpBufferSize=*(long *)(buffer+i2);
230 i2+=sizeof(long);
231
232
233 HeapDefaultFree(buffer);
234 buffer=0;
235
236
[265]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 }
[4]242
243
244 SingleStepCodeBuffer=MakeSingleStepCode();
[313]245
246 //ソースコード
247 extern char *basbuf;
[587]248 basbuf = const_cast<char *>(compiler.GetObjectModule().GetSource(0).GetBuffer());
[4]249
250
251 /////////////////////////////
252 // ブレークポイントを適用
253 /////////////////////////////
254
255 //コードと行番号の関係
[263]256 extern SourceLines oldSourceLines;
[265]257 oldSourceLines = this->_oldSourceLines;
[4]258
259 BreakStepCodeBuffer=pobj_DBBreakPoint->update(OpBuffer,SizeOf_CodeSection);
260
261 //プロセスメモリにコピー
262 extern HANDLE hDebugProcess;
[76]263 SIZE_T accessBytes;
[4]264 WriteProcessMemory(hDebugProcess,(void *)(ULONG_PTR)(dwImageBase+dwRVA_CodeSection),
265 BreakStepCodeBuffer,
[76]266 SizeOf_CodeSection,&accessBytes);
[4]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;
[76]280 SIZE_T accessBytes;
[4]281 IMAGE_DOS_HEADER ImageDosHeader;
[76]282 ReadProcessMemory(hDebugProcess,hModule,&ImageDosHeader,sizeof(IMAGE_DOS_HEADER),&accessBytes);
[4]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
[76]292 ReadProcessMemory(hDebugProcess,(void *)(((ULONG_PTR)hModule)+ImageDosHeader.e_lfanew),&pe_hdr,pe_size,&accessBytes);
[4]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),
[76]300 &accessBytes);
[4]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,
[76]325 &accessBytes);
[4]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
[191]339 if(OpBuffer) free(OpBuffer);
[188]340 OpBuffer=(char *)malloc(SizeOf_CodeSection);
[4]341
342 ReadProcessMemory(hDebugProcess,
343 (void *)(ULONG_PTR)(dwImageBase+dwRVA_CodeSection),OpBuffer,
[76]344 SizeOf_CodeSection,&accessBytes);
[4]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
[265]365 // オブジェクトモジュール
366 compiler.SelectObjectModule( this->objectModule );
367
[4]368 //コードと行番号の関係
[263]369 extern SourceLines oldSourceLines;
[265]370 oldSourceLines = this->_oldSourceLines;
[4]371
372 //グローバル実行領域のサイズ
373 extern int GlobalOpBufferSize;
374 GlobalOpBufferSize=this->GlobalOpBufferSize;
375
[206]376 extern const UserProc *pSub_DebugSys_EndProc;
[4]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 //コードバッファを解放
[182]386 free(OpBuffer);
[4]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.