source: dev/trunk/abdev/BasicCompiler_Common/WatchList.cpp@ 264

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

MetaImplを廃止し、Metaにした。
ObjectModuleクラス、Linkerクラスを用意。

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