This is the mail archive of the
gdb-prs@sourceware.org
mailing list for the GDB project.
[Bug c++/15559] Method call and calling convention
- From: "asmwarrior at gmail dot com" <sourceware-bugzilla at sourceware dot org>
- To: gdb-prs at sourceware dot org
- Date: Tue, 08 Oct 2013 06:19:16 +0000
- Subject: [Bug c++/15559] Method call and calling convention
- Auto-submitted: auto-generated
- References: <bug-15559-4717 at http dot sourceware dot org/bugzilla/>
https://sourceware.org/bugzilla/show_bug.cgi?id=15559
--- Comment #5 from asmwarrior <asmwarrior at gmail dot com> ---
I see that in the file: gdb\sh-tdep.c, the user can specify the calling
convention from the command line, see the source:
-------------------------------------------
void
_initialize_sh_tdep (void)
{
gdbarch_register (bfd_arch_sh, sh_gdbarch_init, NULL);
add_prefix_cmd ("sh", no_class, set_sh_command, "SH specific commands.",
&setshcmdlist, "set sh ", 0, &setlist);
add_prefix_cmd ("sh", no_class, show_sh_command, "SH specific commands.",
&showshcmdlist, "show sh ", 0, &showlist);
add_setshow_enum_cmd ("calling-convention", class_vars, sh_cc_enum,
&sh_active_calling_convention,
_("Set calling convention used when calling target "
"functions from GDB."),
_("Show calling convention used when calling target "
"functions from GDB."),
_("gcc - Use GCC calling convention (default).\n"
"renesas - Enforce Renesas calling convention."),
NULL, NULL,
&setshcmdlist, &showshcmdlist);
}
-------------------------------------------
The variable sh_active_calling_convention is 0 (default) for sh_cc_gcc calling
convention, and 1 for sh_cc_renesas, there is a function:
static int
sh_is_renesas_calling_convention (struct type *func_type)
to determine the function calling convention by some checks:
TYPE_CALLING_CONVENTION (func_type) == DW_CC_GNU_renesas_sh....
Finally, the different calling conversion will change the behavior of
sh_push_dummy_call_*, which is the way GDB make a dummy call.
Under MinGW GCC(maybe not limit in Windows system), it looks like the debug
information is not enough. E.g. the sample code build from MinGW GCC 4.6.x or
4.8.1
-------------------------------------------
int f_c_call(int a)
{
return a;
}
int __attribute__((thiscall)) f_this_call (int b)
{
return b;
}
class Test
{
public:
Test(int value) : _value(value) {}
int m_f_this_call() const __attribute__((thiscall)) { return _value; }
int m_f_c_call() const __attribute__((cdecl)) { return _value; }
private:
int _value;
};
int main()
{
Test test1(123);
Test test2(456);
int value1 = test1.m_f_c_call();
int value2 = test2.m_f_this_call();
value1 = f_c_call(1);
value2 = f_this_call(2);
int value3 = value1+value2;
return 0;
}
-------------------------------------------
Run this inferior under GDB, then type:
maintenance print type f_this_call
result:
type node 0x1b37c58
name '<NULL>' (0x0)
tagname '<NULL>' (0x0)
code 0x7 (TYPE_CODE_FUNC)
length 1
objfile 0x1b29990
target_type 0x1b333c8
type node 0x1b333c8
name 'int' (0x1b34b35)
tagname '<NULL>' (0x0)
code 0x8 (TYPE_CODE_INT)
length 4
objfile 0x1b29990
target_type 0x0
pointer_type 0x0
reference_type 0x0
type_chain 0x1b333c8
instance_flags 0x0
flags
nfields 0 0x0
vptr_basetype 0x0
vptr_fieldno -1
pointer_type 0x0
reference_type 0x0
type_chain 0x1b37c58
instance_flags 0x0
flags TYPE_FLAG_PROTOTYPED
nfields 1 0x1b37cb0
[0] bitpos 0 bitsize 0 type 0x1b333c8 name '<NULL>' (0x0)
type node 0x1b333c8
name 'int' (0x1b34b35)
tagname '<NULL>' (0x0)
code 0x8 (TYPE_CODE_INT)
length 4
objfile 0x1b29990
target_type 0x0
pointer_type 0x0
reference_type 0x0
type_chain 0x1b333c8
instance_flags 0x0
flags
nfields 0 0x0
vptr_basetype 0x0
vptr_fieldno -1
vptr_basetype 0x0
vptr_fieldno -1
calling_convention 1
Type maintenance print type f_c_call, maintenance print type f_c_call,
maintenance print type Test::m_f_c_call, maintenance print type
Test::m_f_this_call, all gives the same result of "calling_convention 1".
So, I think a work around is do the same thing like in "sh-tdep.c", that is: we
see the inferior is build from GCC 4.7 or later, we need to check the
calling_convention by some code snippet like:
TYPE_CODE (func_type) == TYPE_CODE_FUNC and this is a member function
then we should modify the i386_push_dummy_call like function in i386-tdep.c,
oh, do we need a i386-windows-tdeps.c? I see there are files named
amd64-windows-tdeps.c, i386-cygwin-tdeps.c, but I don't see
i386-windows-tdeps.c, the reason may be that i386-tdep.c is a good place to put
the change?
I'm sorry I can't go further to implement this, but I hope some guys can help
to improve this, thanks.
Yuanhui Zhang
--
You are receiving this mail because:
You are on the CC list for the bug.