source: dev/BasicCompiler_Common/WatchList.cpp@ 140

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

traceログ機能を搭載
動的メンバをstl::vectorにまとめた
シンボルをクラス化した

File size: 12.4 KB
Line 
1#include "common.h"
2
3#ifdef _AMD64_
4#include "../BasicCompiler64/opcode.h"
5#else
6#include "../BasicCompiler32/opcode.h"
7#endif
8
9//デバッグ用
10#include "debug.h"
11
12int Debugging_GetArray( const int *SubScripts,char *array,const Type &type,LONG_PTR *plpOffset);
13
14ULONG_PTR Debugging_GetVarPtr(RELATIVE_VAR *pRelativeVar){
15 extern DWORD ImageBase;
16 extern int MemPos_RWSection;
17 int i2;
18
19 if(pRelativeVar->dwKind==VAR_GLOBAL){
20 return ImageBase+MemPos_RWSection+pRelativeVar->offset;
21 }
22 else if( pRelativeVar->dwKind == VAR_REFGLOBAL ){
23 extern HANDLE hDebugProcess;
24 LONG_PTR lpData;
25 SIZE_T accessBytes;
26 ReadProcessMemory(hDebugProcess,
27 (void *)(ImageBase+MemPos_RWSection+pRelativeVar->offset),
28 &lpData,
29 sizeof(LONG_PTR),
30 &accessBytes);
31
32 return lpData;
33 }
34 else if(pRelativeVar->dwKind==VAR_LOCAL){
35 extern HWND hDebugWnd;
36 i2=(int)SendDlgItemMessage(hDebugWnd,IDC_PROCCOMBO,CB_GETCURSEL,0,0);
37 i2=pobj_dti->iProcLevel-i2;
38
39 if(pobj_dti->lplpSpBase[i2]==0) return 0;
40
41 return pobj_dti->lplpSpBase[i2]+pRelativeVar->offset;
42 }
43 else if( pRelativeVar->dwKind == VAR_REFLOCAL ){
44 extern HWND hDebugWnd;
45 i2=(int)SendDlgItemMessage(hDebugWnd,IDC_PROCCOMBO,CB_GETCURSEL,0,0);
46 i2=pobj_dti->iProcLevel-i2;
47
48 if(pobj_dti->lplpSpBase[i2]==0) return 0;
49
50 extern HANDLE hDebugProcess;
51 LONG_PTR lpData;
52 SIZE_T accessBytes;
53 ReadProcessMemory(hDebugProcess,
54 (void *)(pobj_dti->lplpSpBase[i2]+(int)pRelativeVar->offset),
55 &lpData,
56 sizeof(LONG_PTR),
57 &accessBytes);
58
59 return lpData;
60 }
61 else if(pRelativeVar->dwKind==VAR_DIRECTMEM){
62 return pRelativeVar->offset;
63 }
64
65 return 0;
66}
67
68bool Debugging_SetRelativeOffset( Type &type,RELATIVE_VAR *pRelativeVar,char *lpPtrOffset){
69 int array_num;
70
71 _int64 i64data;
72 if( !StaticCalculation( true, lpPtrOffset, 0, &i64data, Type(), 1 ) ){
73 return false;
74 }
75 if( type.IsReal() ){
76 double dbl;
77 memcpy(&dbl,&i64data,sizeof(double));
78 i64data=(_int64)dbl;
79 }
80
81 array_num=(int)i64data;
82
83 if( type.PtrLevel() ){
84 type.PtrLevelDown();
85 array_num *= type.GetSize();
86 }
87 else{
88 //エラー
89 return false;
90 }
91
92 extern HANDLE hDebugProcess;
93 LONG_PTR lpData;
94 SIZE_T accessBytes;
95 lpData=Debugging_GetVarPtr(pRelativeVar);
96 if(!ReadProcessMemory(hDebugProcess,(void *)lpData,&pRelativeVar->offset,sizeof(LONG_PTR),&accessBytes)){
97 return false;
98 }
99 pRelativeVar->dwKind=VAR_DIRECTMEM;
100
101 pRelativeVar->offset+=array_num;
102 return true;
103}
104
105int Debugging_GetMember( const CClass &objClass,char *member,RELATIVE_VAR *pRelativeVar, Type &resultType, BOOL bPrivateAccess){
106 int i2;
107
108 //直接参照に切り替え
109 pRelativeVar->offset=(LONG_PTR)Debugging_GetVarPtr(pRelativeVar);
110 pRelativeVar->dwKind=VAR_DIRECTMEM;
111
112 //クラス、配列の構成要素を解析する
113 char VarName[VN_SIZE]; //変数名
114 char array[VN_SIZE]; //第1次配列
115 char lpPtrOffset[VN_SIZE]; //第2次配列
116 char NestMember[VN_SIZE]; //入れ子メンバ
117 CClass::RefType refType;
118 lstrcpy(VarName,member);
119 if(!GetVarFormatString(VarName,array,lpPtrOffset,NestMember, refType ) ) return 0;
120
121
122 ////////////////////////////
123 // メンバオフセットを取得
124 ////////////////////////////
125
126 int memberIndex;
127 int offset = objClass.GetMemberOffset( VarName, &memberIndex );
128 if(memberIndex==objClass.GetDynamicMembers().size()) return 0;
129
130 CMember *pMember = objClass.GetDynamicMembers()[memberIndex];
131
132
133 //アクセシビリティをチェック
134 if(( bPrivateAccess==0 && pMember->IsPrivate() )||
135 pMember->IsNoneAccess() ){
136 return 0;
137 }
138 else if(bPrivateAccess==0&&pMember->IsProtected())
139 return 0;
140
141 resultType = pMember->GetType();
142
143 //ポインタ変数の場合
144 if( resultType.IsPointer() ){
145 if(pMember->SubScripts[0]==-1){
146 lstrcpy(lpPtrOffset,array);
147 array[0]=0;
148 }
149 }
150 else{
151 if(lpPtrOffset[0]) return 0;
152 }
153
154 pRelativeVar->offset+=offset;
155
156 if(array[0]){
157 //配列オフセット
158 i2=Debugging_GetArray(
159 pMember->SubScripts,
160 array,
161 resultType,
162 &pRelativeVar->offset);
163 if(i2==0){
164 //式エラー
165 return 0;
166 }
167 if(i2==-1){
168 //アクセスエラー
169 return -1;
170 }
171 }
172 else if(pMember->SubScripts[0]!=-1){
173 resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
174 }
175
176 if(NestMember[0]){
177 //入れ子構造の場合
178
179 if( resultType.IsObject() || resultType.IsStruct() ){
180 if( refType != CClass::Dot ) return 0;
181
182 if( resultType.IsObject() ){
183 extern HANDLE hDebugProcess;
184 LONG_PTR lpData;
185 SIZE_T accessBytes;
186 lpData=Debugging_GetVarPtr(pRelativeVar);
187 if(!ReadProcessMemory(hDebugProcess,(void *)lpData,&pRelativeVar->offset,sizeof(LONG_PTR),&accessBytes)) return -1;
188 pRelativeVar->dwKind=VAR_DIRECTMEM;
189 }
190 }
191 else if( resultType.IsObjectPtr() || resultType.IsStructPtr() ){
192 //構造体ポインタ型メンバ変数
193
194 if(lpPtrOffset[0]){
195 if( refType != CClass::Dot ) return 0;
196
197 //直接参照に切り替え
198 Debugging_SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
199
200 lpPtrOffset[0]=0;
201 }
202 else{
203 if( refType != CClass::Pointer ) return 0;
204
205 extern HANDLE hDebugProcess;
206 LONG_PTR lpData;
207 SIZE_T accessBytes;
208 lpData=Debugging_GetVarPtr(pRelativeVar);
209 if(!ReadProcessMemory(hDebugProcess,(void *)lpData,&pRelativeVar->offset,sizeof(LONG_PTR),&accessBytes)) return -1;
210 pRelativeVar->dwKind=VAR_DIRECTMEM;
211 }
212 }
213
214 i2=Debugging_GetMember(pMember->GetType().GetClass(),
215 NestMember,
216 pRelativeVar,
217 resultType,
218 0);
219 if(i2==0){
220 //式エラー
221 return 0;
222 }
223 if(i2==-1){
224 //アクセスエラー
225 return -1;
226 }
227 }
228
229 if(lpPtrOffset[0]){
230 Debugging_SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
231 }
232
233 return 1;
234}
235int Debugging_GetArray( const int *SubScripts,char *array,const Type &type,LONG_PTR *plpOffset){
236 extern HANDLE hHeap;
237 int i,i2,i3,i4,i5,array_offset;
238 char temporary[VN_SIZE],*pParm[MAX_PARMS];
239
240 for(i=0,i2=0,i3=0;;i++,i2++){
241 if(array[i]=='('){
242 i4=GetStringInPare(temporary+i2,array+i);
243 i+=i4-1;
244 i2+=i4-1;
245 continue;
246 }
247 if(array[i]=='['){
248 i4=GetStringInBracket(temporary+i2,array+i);
249 i+=i4-1;
250 i2+=i4-1;
251 continue;
252 }
253 if(array[i]==','||array[i]=='\0'){
254 if(SubScripts[i3]==-1){
255 for(i3--;i3>=0;i3--) HeapDefaultFree(pParm[i3]);
256 return 0;
257 }
258
259 temporary[i2]=0;
260
261 pParm[i3]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
262 lstrcpy(pParm[i3],temporary);
263
264 i3++;
265
266 if(array[i]=='\0'){
267 if(SubScripts[i3]!=-1){
268 for(i3--;i3>=0;i3--) HeapDefaultFree(pParm[i3]);
269 return 0;
270 }
271 break;
272 }
273
274 i2=-1;
275 continue;
276 }
277 temporary[i2]=array[i];
278 }
279
280 array_offset=0;
281
282 for(i=i3-1;i>=0;i--){
283 _int64 i64data;
284 Type resultType;
285 bool isMemoryAccessError;
286 if( !StaticCalculation(true, pParm[i],0,&i64data,resultType,1, &isMemoryAccessError ) ){
287 //式エラー
288 return 0;
289 }
290 if(isMemoryAccessError){
291 //アクセスエラー
292 return -1;
293 }
294
295 if(resultType.IsReal()){
296 double dbl;
297 memcpy(&dbl,&i64data,sizeof(double));
298 i64data=(_int64)dbl;
299 }
300 i5=(int)i64data;
301
302 for(i2=i+1,i4=1;i2<i3;i2++) i4*=SubScripts[i2]+1;
303
304 array_offset+=i5*i4;
305
306 HeapDefaultFree(pParm[i]);
307 }
308
309 array_offset *= type.GetSize();
310
311 *plpOffset+=array_offset;
312
313 return 1;
314}
315ULONG_PTR Debugging_GetThisPtrOffset(LONG_PTR obp_Rip){
316 GlobalProc *pUserProc = GetSubFromObp(obp_Rip);
317
318 foreach( Variable *pVar, pUserProc->localVars ){
319 if( pVar->GetName() == "_System_LocalThis" ){
320 return pVar->offset;
321 }
322 }
323 return 0;
324}
325int Debugging_GetVarOffset( char *variable,RELATIVE_VAR *pRelativeVar, Type &resultType, int *pss){
326 extern HANDLE hDebugProcess;
327 int i2,i3;
328 char member[VN_SIZE],VarName[VN_SIZE],array[VN_SIZE],lpPtrOffset[VN_SIZE];
329 LONG_PTR lpData;
330 SIZE_T accessBytes;
331
332 lstrcpy(VarName,variable);
333 CClass::RefType refType;
334 GetVarFormatString(VarName,array,lpPtrOffset,member,refType);
335
336 const int *pSubScripts;
337 bool isArray;
338
339
340 /////////////////
341 // ローカル変数
342 /////////////////
343 if( UserProc::IsLocalAreaCompiling() ){
344 const Variable *pVar = UserProc::CompilingUserProc().localVars.Find( Symbol( VarName ) );
345
346 if( pVar ){
347 //ポインタ変数の場合
348 if( pVar->IsPointer() ){
349 if( !pVar->IsArray() ){
350 lstrcpy(lpPtrOffset,array);
351 array[0]=0;
352 }
353 }
354 else{
355 if(lpPtrOffset[0]) return 0;
356 }
357
358 pRelativeVar->offset = pVar->offset;
359 if( pVar->IsRef() ){
360 pRelativeVar->dwKind=VAR_REFLOCAL;
361 }
362 else{
363 pRelativeVar->dwKind=VAR_LOCAL;
364 }
365 resultType = *pVar;
366 isArray = pVar->IsArray();
367 pSubScripts = pVar->GetSubScriptsPtr();
368 }
369 }
370
371 if(pobj_CompilingClass){
372 ///////////////////////
373 // クラスメンバの参照
374 ///////////////////////
375
376 if(memicmp(variable,"This.",5)==0){
377 //Thisオブジェクトのメンバを参照するとき
378 SlideString(variable+5,-5);
379 lstrcpy(VarName,variable);
380 }
381 else{
382 //クラス内メンバを参照するとき(通常)
383
384 bool isFound = false;
385 BOOST_FOREACH( CMember *pMember, pobj_CompilingClass->GetDynamicMembers() ){
386 if( pMember->GetName() == VarName ){
387 isFound = true;
388 break;
389 }
390 }
391 if( !isFound ) goto NonClassMember;
392 }
393
394 /////////////////////////////
395 // thisポインタを取得
396
397 extern HWND hDebugWnd;
398 i2=(int)SendDlgItemMessage(hDebugWnd,IDC_PROCCOMBO,CB_GETCURSEL,0,0);
399 i2=pobj_dti->iProcLevel-i2;
400
401 lpData=Debugging_GetThisPtrOffset(pobj_dti->lplpObp[i2]);
402 if(!lpData){
403 //式エラー
404 return 0;
405 }
406 lpData+=pobj_dti->lplpSpBase[i2];
407 if(!ReadProcessMemory(hDebugProcess,(void *)lpData,&pRelativeVar->offset,sizeof(LONG_PTR),&accessBytes)){
408 //メモリにアクセスできないとき
409 return -1;
410 }
411
412 pRelativeVar->dwKind=VAR_DIRECTMEM;
413
414 i3=Debugging_GetMember(*pobj_CompilingClass,variable,pRelativeVar,resultType,1);
415 if(i3==0){
416 //式エラー
417 return 0;
418 }
419 if(i3==-1){
420 //アクセスエラー
421 return -1;
422 }
423
424 return 1;
425 }
426
427NonClassMember:
428
429 {
430 ///////////////////
431 // グローバル変数
432 ///////////////////
433
434 const Variable *pVar = globalVars.Find( VarName );
435 if( !pVar ){
436 //一致しないとき
437 return 0;
438 }
439
440 //ポインタ変数の場合
441 if( pVar->IsPointer() ){
442 if( !pVar->IsArray() ){
443 lstrcpy(lpPtrOffset,array);
444 array[0]=0;
445 }
446 }
447 else{
448 if(lpPtrOffset[0]) return 0;
449 }
450
451 pRelativeVar->offset=pVar->offset;
452 if(pVar->IsRef()) pRelativeVar->dwKind=VAR_REFGLOBAL;
453 else pRelativeVar->dwKind=VAR_GLOBAL;
454 resultType = *pVar;
455 isArray = pVar->IsArray();
456 pSubScripts=pVar->GetSubScriptsPtr();
457 }
458
459
460 if(array[0]==0&&isArray){
461 //配列の先頭ポインタを示す場合
462 resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
463 if(pss) memcpy(pss,pSubScripts,MAX_ARRAYDIM*sizeof(int));
464 return 1;
465 }
466
467 if(array[0]){
468 i3=Debugging_GetArray(pSubScripts,array,resultType,&pRelativeVar->offset);
469 if(i3==0){
470 //式エラー
471 return 0;
472 }
473 if(i3==-1){
474 //アクセスエラー
475 return -1;
476 }
477 }
478 if(member[0]){
479 if( resultType.IsObject() || resultType.IsStruct() ){
480 //実態オブジェクトのメンバを参照(obj.member)
481 if( refType != CClass::Dot ){
482 return 0;
483 }
484
485 i3=Debugging_GetMember(resultType.GetClass(),member,pRelativeVar,resultType,0);
486 if(i3==0){
487 //式エラー
488 return 0;
489 }
490 if(i3==-1){
491 //アクセスエラー
492 return -1;
493 }
494 }
495 else if( resultType.IsObjectPtr() || resultType.IsStructPtr() ){
496 //ポインタオブジェクトが示すメンバを参照
497 if(lpPtrOffset[0]){
498 //pObj[n].member
499 if( refType != CClass::Dot ) return 0;
500 Debugging_SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
501
502 i3=Debugging_GetMember(resultType.GetClass(),member,pRelativeVar,resultType,0);
503 if(i3==0){
504 //式エラー
505 return 0;
506 }
507 if(i3==-1){
508 //アクセスエラー
509 return -1;
510 }
511 }
512 else{
513 //pObj->member
514 if( refType != CClass::Pointer ) return 0;
515
516 pRelativeVar->offset=Debugging_GetVarPtr(pRelativeVar);
517 pRelativeVar->dwKind=VAR_DIRECTMEM;
518
519 if(!ReadProcessMemory(hDebugProcess,(void *)pRelativeVar->offset,&lpData,sizeof(LONG_PTR),&accessBytes)) return -1;
520 pRelativeVar->offset=lpData;
521
522 i3=Debugging_GetMember(resultType.GetClass(),member,pRelativeVar,resultType,0);
523 if(i3==0){
524 //式エラー
525 return 0;
526 }
527 if(i3==-1){
528 //アクセスエラー
529 return -1;
530 }
531 }
532 }
533 else{
534 return 0;
535 }
536 return 1;
537 }
538
539 if(lpPtrOffset[0]){
540 if(!Debugging_SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset)) return 0;
541 }
542
543 return 1;
544}
Note: See TracBrowser for help on using the repository browser.