--- gdb/eval.c | 7 +++++++ gdb/i386-tdep.c | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/gdb/eval.c b/gdb/eval.c index e83bfdf..9ae802f 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -49,6 +49,10 @@ /* This is defined in valops.c */ extern int overload_resolution; +/* this variable is to notify i386_push_dummy_call that an + function is static member function, it is a hack */ +extern int i386_windows_static_memfun; + /* Prototypes for local functions. */ static struct value *evaluate_subexp_for_sizeof (struct expression *, int *); @@ -1668,7 +1672,10 @@ evaluate_subexp_standard (struct type *expect_type, argvec[1] = argvec[0]; nargs--; argvec++; + i386_windows_static_memfun = 1; } + else + i386_windows_static_memfun = 0; } else if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR) { diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index b159b49..551d630 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -2396,6 +2396,10 @@ i386_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp, CORE_ADDR funaddr, /* Keep the stack aligned. */ return sp - 16; } +/* This is the hack to handle the non-static member function to thiscall + calling convention mode, this variable is updated in eval.c of the + static member function check */ +int i386_windows_static_memfun = 0; static CORE_ADDR i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function, @@ -2408,6 +2412,27 @@ i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function, int i; int write_pass; int args_space = 0; + struct type *func_type = value_type (function); + int i386_windows_thiscall = 0; + + if (func_type) + { + func_type = check_typedef (func_type); + + if (TYPE_CODE (func_type) == TYPE_CODE_PTR) + func_type = check_typedef (TYPE_TARGET_TYPE (func_type)); + + if( (TYPE_CODE (func_type) == TYPE_CODE_METHOD) + && (nargs > 0) + && i386_windows_static_memfun == 0 ) + { + /* a.f(5,6); + args[0] = this pointer; + args[1] = 5; + args[2] = 6; */ + i386_windows_thiscall = 1; + } + } /* Determine the total space required for arguments and struct return address in a first pass (allowing for 16-byte-aligned @@ -2430,7 +2455,7 @@ i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function, args_space += 4; } - for (i = 0; i < nargs; i++) + for (i = i386_windows_thiscall; i < nargs; i++) { int len = TYPE_LENGTH (value_enclosing_type (args[i])); @@ -2482,6 +2507,12 @@ i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* ...and fake a frame pointer. */ regcache_cooked_write (regcache, I386_EBP_REGNUM, buf); + if (i386_windows_thiscall) + { + /* args[0] refer to the last argument which is the this pointer */ + regcache_cooked_write (regcache, I386_ECX_REGNUM, value_contents_all(args[0])); + } + /* MarkK wrote: This "+ 8" is all over the place: (i386_frame_this_id, i386_sigtramp_frame_this_id, i386_dummy_id). It's there, since all frame unwinders for -- 1.8.4.msysgit.0 è¿éæå 个é®é¢ï¼ 1ï¼æ³¨éé®é¢ç¡®å®æç¹ä¹±ï¼å¯ä»¥åè°æ´ä¸ä¸ï¼èä¸æè¿ä¸ªpatchä¸æçè¯ï¼ä¼è®©GDBåªæ¯æMinGW4.7.0以åççæ¬ï¼æMinGW4.6.xå以åççæ¬ç»æå¼æäºï¼æ以æ好æ¥æ£æµä¸ä¸å½åè£ è½½çBFDäºè¿å¶æ件æ¯å¥çæ¬çGCCç¼è¯åºæ¥çï¼å¦ææ¯4.7.0æè 以åçæ¬ï¼å°±è¿è¡thiscallçç¸åºè°æ´ã 2ï¼GDBéé¢æä¸ä¸ªå ³äºstatic member functionçæ£æµï¼å¨evaléé¢ï¼æå¨è¿ä¸ªå°æ¹å äºä¸ä¸ªå ¨å±åéi386_windows_static_memfunï¼ if (static_memfuncp) { argvec[1] = argvec[0]; nargs--; argvec++; i386_windows_static_memfun = 1; } else i386_windows_static_memfun = 0; } å 为æç¥éï¼ä¹å®é æµè¯è¿ï¼ï¼å¯¹äºstaticçmember functionï¼å®é ä¸æ¯æ²¡æthis æéçï¼GDBéé¢ä¹è¿è¡äº ânargs--âè¿æ ·çå¤çã ä½æ¯å¯¹äºdummy_callå½æ°èè¨ï¼å®æ¥æçä¿¡æ¯å¤ªå°äºï¼æåªè½å¤æåºæ¥ä»æ¯ä¸æ¯ç±»æåå½æ°ï¼if( (TYPE_CODE (func_type) == TYPE_CODE_METHOD)ï¼å¦å¤æå°±éè¦ç¨å°è¿ä¸ªi386_windows_static_memfunåéäºï¼ææ¬æ¥æ³è®©è¿ä¸ªåéä½ä¸ºå½æ°åæ°ä¸å±ä¸å±ä¼ éå° dummy callçéé¢ï¼ä½æ¯æè§è¿æ ·å¯¹ä»£ç æ¹å¨å®å¨å¤ªå¤äºã è°¢è°¢ä½ çåå¤ï¼å¸æå¯ä»¥è¿ä¸æ¥æ¢è®¨åæ¹è¿ã