RE: Calling __stdcall functions in the inferior

Pierre Muller
2012-10-15T13:17:06Z

Sorry, the email below was supposed to
be for the list, but I forgot to check the recipient and sent
it only to Eli first.

I think that I found a possible cause
of this problem. It is related to an assumption
that is currently made in gdb source about windows DLL
that the '.text' section starts at offset 0x1000 relative
to the image base.
This assumption is wrong for a number of Windows system DLLs.
I will send a RFC email proposing a fix of this
problem.

Pierre

> -----Message d'origine-----
> De : Pierre Muller [mailto:pierre.muller@ics-cnrs.unistra.fr]
> Envoyé : vendredi 12 octobre 2012 16:46
> À : 'Eli Zaretskii'
> Objet : RE: Calling __stdcall functions in the inferior
>
> Hi Eli,
>
> I do get the same problem.
> (but not with the @0 suffix!)
> 1> call 'GetLastError@0'()
> $9 = 126
> 1> call 'GetLastError'()
> gdb: unknown target exception 0xc0000008 at 0x773612f7
>
> Program received signal ?, Unknown signal.
> 0x7750f9d2 in ntdll!RtlUpdateClonedSRWLock () from
> C:\Windows\system32\ntdll.dll
> The program being debugged was signaled while in a function called from
GDB.
> GDB remains in the frame where the signal was received.
> To change this behavior use "set unwindonsignal on".
> Evaluation of the expression containing the function
> (KERNEL32!GetLastError) will be abandoned.
> When the function is done executing, GDB will silently stop.
>
>
> Did you try to disassemble the code at GetLastError?
>
> On my Windows64 bit machine, that code looks quite weird:
> Maybe this is Windows64 bit specific?... No,
> I checked on a 32bit machine, and found the same problem.
>
> 1> x /10i &GetLastError
> 0x75758967 <KERNEL32!GetLastError>: jne 0x75758968
> <KERNEL32!GetLastError+1>
> 0x75758969 <KERNEL32!GetLastError+2>: jae 0x75758987
> <KERNEL32!GetConsoleCursorMode>
> 0x7575896b <KERNEL32!GetLastError+4>: pushl 0x18(%ebx)
> 0x7575896e <KERNEL32!GetLastError+7>: call *0x756c0044
> 0x75758974 <KERNEL32!GetLastError+13>: test %al,%al
> 0x75758976 <KERNEL32!GetLastError+15>: je 0x75758b4a
> <SetConsoleScreenBufferInfoEx+3>
> 0x7575897c <KERNEL32!GetLastError+21>: mov -0x240(%ebp),%eax
> 0x75758982 <KERNEL32!GetLastError+27>: mov %eax,-0x370(%ebp)
> 0x75758988 <KERNEL32!GetConsoleCursorMode+1>: movzwl -
> 0x244(%ebp),%eax
> 0x7575898f <KERNEL32!GetConsoleCursorMode+8>: xor %ecx,%ecx
>
> Exploring the 'GetLastError@0',
> I find:
>
> 1> disas 'GetLastError@0'
> Dump of assembler code for function GetLastError@0:
> 0x00722a9c <+0>: jmp *0x9a7528
> 0x00722aa2 <+6>: nop
> 0x00722aa3 <+7>: nop
> End of assembler dump.
> 1> x /x 0x9a7528
> 0x9a7528 <_imp__GetLastError@0>: 0x756c11c0
> 1> x /10i 0x756c11c0
> 0x756c11c0 <KERNEL32!GetPrivateProfileStructA+6032>: jmp 0x756c11c7
> <KERNEL32!GetPrivateProfileStructA+6039>
> 0x756c11c2 <KERNEL32!GetPrivateProfileStructA+6034>: nop
> 0x756c11c3 <KERNEL32!GetPrivateProfileStructA+6035>: nop
> 0x756c11c4 <KERNEL32!GetPrivateProfileStructA+6036>: nop
> 0x756c11c5 <KERNEL32!GetPrivateProfileStructA+6037>: nop
> 0x756c11c6 <KERNEL32!GetPrivateProfileStructA+6038>: nop
> 0x756c11c7 <KERNEL32!GetPrivateProfileStructA+6039>: jmp *0x756c0d9c
> 0x756c11cd <KERNEL32!GetPrivateProfileStructA+6045>: nop
> 0x756c11ce <KERNEL32!GetPrivateProfileStructA+6046>: nop
> 0x756c11cf <KERNEL32!GetPrivateProfileStructA+6047>: nop
> 1> x /10i 0x756c11c7
> 0x756c11c7 <KERNEL32!GetPrivateProfileStructA+6039>: jmp *0x756c0d9c
> 0x756c11cd <KERNEL32!GetPrivateProfileStructA+6045>: nop
> 0x756c11ce <KERNEL32!GetPrivateProfileStructA+6046>: nop
> 0x756c11cf <KERNEL32!GetPrivateProfileStructA+6047>: nop
> 0x756c11d0 <KERNEL32!GetPrivateProfileStructA+6048>: nop
> 0x756c11d1 <KERNEL32!GetPrivateProfileStructA+6049>: nop
> 0x756c11d2 <KERNEL32!GetPrivateProfileStructA+6050>: nop
> 0x756c11d3 <KERNEL32!GetPrivateProfileStructA+6051>: nop
> 0x756c11d4 <KERNEL32!GetPrivateProfileStructA+6052>: nop
> 0x756c11d5 <KERNEL32!GetPrivateProfileStructA+6053>: nop
> 1> x /x 0x756c0d9c
> 0x756c0d9c <KERNEL32!GetPrivateProfileStructA+4972>: 0x74e6786a
> 1> x /10i 0x74e6786a
> 0x74e6786a <KERNELBASE!GetLocaleInfoA>: mov %fs:0x18,%eax
> 0x74e67870 <KERNELBASE!GetLocaleInfoA+6>: mov 0x34(%eax),%eax
> 0x74e67873 <KERNELBASE!GetLocaleInfoA+9>: ret
> This looks like the real code for GetLastError function,
> but it is certainly not the same as: 0x75758967
>
> I am wondering if this is a problem of DLL information reading...
>
> Pierre Muller
>
>
> > -----Message d'origine-----
> > De : gdb-owner@sourceware.org [mailto:gdb-owner@sourceware.org] De la
part
> > de Eli Zaretskii
> > Envoyé : vendredi 12 octobre 2012 15:26
> > À : Pedro Alves
> > Cc : mark.kettenis@xs4all.nl; gdb@sourceware.org
> > Objet : Re: Calling __stdcall functions in the inferior
> >
> > > Date: Fri, 12 Oct 2012 12:27:53 +0100
> > > From: Pedro Alves <palves@redhat.com>
> > > CC: Mark Kettenis <mark.kettenis@xs4all.nl>, gdb@sourceware.org
> > >
> > > In gcc/config/i386/winnt.c:
> > >
> > > /* Return string which is the function name, identified by ID,
> modified
> > > with a suffix consisting of an atsign (@) followed by the number
of
> > > bytes of arguments. If ID is NULL use the DECL_NAME as base. If
> > > FASTCALL is true, also add the FASTCALL_PREFIX.
> > > Return NULL if no change required. */
> > >
> > > static tree
> > > gen_stdcall_or_fastcall_suffix (tree decl, tree id, bool fastcall)
> > > {
> > >
> > > As you see above, fastcall also has identifiable decoration.
> >
> > Thanks.