From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 386 invoked by alias); 15 Oct 2012 13:36:07 -0000 Received: (qmail 339 invoked by uid 22791); 15 Oct 2012 13:36:05 -0000 X-SWARE-Spam-Status: No, hits=-1.0 required=5.0 tests=AWL,BAYES_05,KHOP_THREADED,MSGID_MULTIPLE_AT X-Spam-Check-By: sourceware.org Received: from mailhost.u-strasbg.fr (HELO mailhost.u-strasbg.fr) (130.79.200.153) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 15 Oct 2012 13:36:00 +0000 Received: from md16.u-strasbg.fr (md16.u-strasbg.fr [130.79.200.206]) by mailhost.u-strasbg.fr (8.14.3/jtpda-5.5pre1) with ESMTP id q9FDZuGe062288 for ; Mon, 15 Oct 2012 15:35:57 +0200 (CEST) (envelope-from pierre.muller@ics-cnrs.unistra.fr) Received: from mailserver.u-strasbg.fr (ms14.u-strasbg.fr [130.79.204.114]) by md16.u-strasbg.fr (8.14.3/jtpda-5.5pre1) with ESMTP id q9FDZuO3001381 for ; Mon, 15 Oct 2012 15:35:56 +0200 (envelope-from pierre.muller@ics-cnrs.unistra.fr) Received: from E6510Muller (gw-ics.u-strasbg.fr [130.79.210.225]) (user=mullerp mech=LOGIN) by mailserver.u-strasbg.fr (8.14.3/jtpda-5.5pre1) with ESMTP id q9FDZuPT012378 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NO) for ; Mon, 15 Oct 2012 15:35:56 +0200 (envelope-from pierre.muller@ics-cnrs.unistra.fr) From: "Pierre Muller" To: References: <83a9vs89r9.fsf@gnu.org> <201210120953.q9C9rqfu020865@glazunov.sibelius.xs4all.nl> <834nm07z0s.fsf@gnu.org> <5077FEB9.4030304@redhat.com> <83y5jb7rfe.fsf@gnu.org> In-Reply-To: <83y5jb7rfe.fsf@gnu.org> Subject: [RFC] Fix .text section offset for windows DLL (was Calling __stdcall functions in the inferior) Date: Mon, 15 Oct 2012 13:36:00 -0000 Message-ID: <006001cdaada$00c81f00$02585d00$@muller@ics-cnrs.unistra.fr> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0061_01CDAAEA.C450EF00" Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2012-10/txt/msg00216.txt.bz2 This is a multi-part message in MIME format. ------=_NextPart_000_0061_01CDAAEA.C450EF00 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-length: 2770 Eli reported a problem with=20 GDB trying to call a function in kernel32.dll. The idea that the calling convention was responsible for the signal when trying to call a function declared in kernel32 dll did not make muich sense for a function like GetLastError, which has no parameters.=20 All i386 calling convention agree that simple return values should be in register EAX. Anyhow an error on location of return value should only have the effect of losing the correct return value but never generate a signal... After some investigation, I noticed that the minimal symbol GetLastError was offset by 0xf0000 respective to the '_imp__GetLastError@0'. The patch attached allowed me to call (gdb) call GetLastError () And get a simple=20 $2 =3D 126 (for instance, depending on when you do the call). Could someone please test the patch and=20 confirm that it does fix the problem? The main fix consists in a new function pe_text_section_offset that I added to coff-pe-read.c source, which allows to fetch the real offset of the .text section relative to the image base, instead of assuming 0x1000. I tried to leave the code in windows_xfer_shared_library "backward compatible", in the sense that if the DLL is not available (as might happen=20 using gdbserver) we still default to 0x1000 value. In fact, the patch contains a second fix about the parsing of exported symbols, which currently can mix symbol names and associated RVA addresses if some function had a imposed ordinal value (which can lead to=20 empty entries in the RVA addresses array). =20 I did not separate the two parts as I was unsure if=20 they are really independent. Comments most welcome, Pierre Muller GDB pascal language maintainer > -----Message d'origine----- > De=A0: gdb-owner@sourceware.org [mailto:gdb-owner@sourceware.org] De la p= art > de Eli Zaretskii > Envoy=E9=A0: vendredi 12 octobre 2012 15:26 > =C0=A0: Pedro Alves > Cc=A0: mark.kettenis@xs4all.nl; gdb@sourceware.org > Objet=A0: Re: Calling __stdcall functions in the inferior >=20 > > Date: Fri, 12 Oct 2012 12:27:53 +0100 > > From: Pedro Alves > > CC: Mark Kettenis , 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. >=20 > Thanks. ------=_NextPart_000_0061_01CDAAEA.C450EF00 Content-Type: application/octet-stream; name="fix-dll-offset.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="fix-dll-offset.patch" Content-length: 8652 projecttype:gdb=0A= revision:HEAD=0A= email:muller@ics.u-strasbg.fr=0A= =0A= 2012-10-15 Pierre Muller =0A= =0A= * coff-pe-read.h (pe_text_section_offset): Declare new function.=0A= * coff-pe-read.c (pe_as16): New function.=0A= (read_pe_exported_syms): Use ordinal of function to=0A= retrieve correct RVA address of function.=0A= (pe_text_section_offset): New function.=0A= =0A= * windows-tdep.c (windows_xfer_shared_library): Use=0A= pe_text_section_offset function instead of possibly wrong=0A= 0x1000 constant for .text sextion offset.=0A= =0A= =0A= Index: src/gdb/coff-pe-read.h=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= RCS file: /cvs/src/src/gdb/coff-pe-read.h,v=0A= retrieving revision 1.11=0A= diff -u -p -r1.11 coff-pe-read.h=0A= --- src/gdb/coff-pe-read.h 4 Jan 2012 08:17:00 -0000 1.11=0A= +++ src/gdb/coff-pe-read.h 15 Oct 2012 12:36:49 -0000=0A= @@ -21,11 +21,15 @@=0A= =20=0A= #if !defined (COFF_PE_READ_H)=0A= #define COFF_PE_READ_H=0A= +#include "defs.h"=0A= =20=0A= struct objfile;=0A= +struct bfd;=0A= =20=0A= /* Read the export table and convert it to minimal symbol table=0A= entries */=0A= extern void read_pe_exported_syms (struct objfile *objfile);=0A= =20=0A= +extern CORE_ADDR pe_text_section_offset (struct bfd *abfd);=0A= +=0A= #endif /* !defined (COFF_PE_READ_H) */=0A= Index: src/gdb/coff-pe-read.c=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= RCS file: /cvs/src/src/gdb/coff-pe-read.c,v=0A= retrieving revision 1.17=0A= diff -u -p -r1.17 coff-pe-read.c=0A= --- src/gdb/coff-pe-read.c 4 Jan 2012 08:17:00 -0000 1.17=0A= +++ src/gdb/coff-pe-read.c 15 Oct 2012 12:36:49 -0000=0A= @@ -170,6 +170,14 @@ pe_get32 (bfd *abfd, int where)=0A= }=0A= =20=0A= static unsigned int=0A= +pe_as16 (void *ptr)=0A= +{=0A= + unsigned char *b =3D ptr;=0A= +=0A= + return b[0] + (b[1] << 8);=0A= +}=0A= +=0A= +static unsigned int=0A= pe_as32 (void *ptr)=0A= {=0A= unsigned char *b =3D ptr;=0A= @@ -336,26 +344,119 @@ read_pe_exported_syms (struct objfile *o=0A= {=0A= /* Pointer to the names vector. */=0A= unsigned long name_rva =3D pe_as32 (erva + name_rvas + i * 4);=0A= + /* Retrieve ordinal value */=0A= +=0A= + unsigned long ordinal =3D pe_as16 (erva + ordinals + i * 2);=0A= +=0A= =20=0A= /* Pointer to the function address vector. */=0A= - unsigned long func_rva =3D pe_as32 (erva + exp_funcbase + i * 4);=0A= + /* This is relatived to ordinal value. */=0A= + unsigned long func_rva =3D pe_as32 (erva + exp_funcbase +=0A= + ordinal * 4);=0A= =20=0A= /* Find this symbol's section in our own array. */=0A= int sectix =3D 0;=0A= + int section_found =3D 0;=0A= =20=0A= for (sectix =3D 0; sectix < PE_SECTION_TABLE_SIZE; ++sectix)=0A= {=0A= if ((func_rva >=3D section_data[sectix].rva_start)=0A= && (func_rva < section_data[sectix].rva_end))=0A= {=0A= + section_found =3D 1;=0A= add_pe_exported_sym (erva + name_rva,=0A= func_rva,=0A= section_data + sectix, dll_name, objfile);=0A= break;=0A= }=0A= }=0A= + if (!section_found)=0A= + {=0A= + char * forward_name =3D (char *) (erva + func_rva);=0A= + char * funcname =3D (char *) (erva + name_rva);=0A= + if ((func_rva >=3D export_rva)=20=0A= + && (func_rva < export_rva + export_size))=20=0A= + printf ("%s is a forward to %s\n", funcname, forward_name);=0A= + }=0A= }=0A= =20=0A= /* Discard expdata. */=0A= do_cleanups (back_to);=0A= }=0A= +=0A= +CORE_ADDR=0A= +pe_text_section_offset (struct bfd *abfd)=0A= +=0A= +{=0A= + bfd *dll =3D abfd;=0A= + unsigned long pe_header_offset, opthdr_ofs, num_entries, i;=0A= + unsigned long export_rva, export_size, nsections, secptr, expptr;=0A= + unsigned long exp_funcbase;=0A= + unsigned char *expdata, *erva;=0A= + unsigned long name_rvas, ordinals, nexp, ordbase;=0A= + char *dll_name;=0A= + int is_pe64 =3D 0;=0A= + int is_pe32 =3D 0;=0A= +=0A= + char const *target =3D bfd_get_target (dll);=0A= +=0A= + is_pe64 =3D (strcmp (target, "pe-x86-64") =3D=3D 0=0A= + || strcmp (target, "pei-x86-64") =3D=3D 0);=0A= + is_pe32 =3D (strcmp (target, "pe-i386") =3D=3D 0=0A= + || strcmp (target, "pei-i386") =3D=3D 0=0A= + || strcmp (target, "pe-arm-wince-little") =3D=3D 0=0A= + || strcmp (target, "pei-arm-wince-little") =3D=3D 0);=0A= +=0A= + if (!is_pe32 && !is_pe64)=0A= + {=0A= + /* This is not a recognized PE format file. Abort now, because=0A= + the code is untested on anything else. *FIXME* test on=0A= + further architectures and loosen or remove this test. */=0A= + return 0;=0A= + }=0A= +=0A= + /* Get pe_header, optional header and numbers of export entries. */=0A= + pe_header_offset =3D pe_get32 (dll, 0x3c);=0A= + opthdr_ofs =3D pe_header_offset + 4 + 20;=0A= + if (is_pe64)=0A= + num_entries =3D pe_get32 (dll, opthdr_ofs + 108);=0A= + else=0A= + num_entries =3D pe_get32 (dll, opthdr_ofs + 92);=0A= +=0A= + if (num_entries < 1) /* No exports. */=0A= + {=0A= + return 0;=0A= + }=0A= +=0A= + if (is_pe64)=0A= + {=0A= + export_rva =3D pe_get32 (dll, opthdr_ofs + 112);=0A= + export_size =3D pe_get32 (dll, opthdr_ofs + 116);=0A= + }=0A= + else=0A= + {=0A= + export_rva =3D pe_get32 (dll, opthdr_ofs + 96);=0A= + export_size =3D pe_get32 (dll, opthdr_ofs + 100);=0A= + }=0A= + nsections =3D pe_get16 (dll, pe_header_offset + 4 + 2);=0A= + secptr =3D (pe_header_offset + 4 + 20 +=0A= + pe_get16 (dll, pe_header_offset + 4 + 16));=0A= + expptr =3D 0;=0A= +=0A= + /* Get the rva and size of the export section. */=0A= + for (i =3D 0; i < nsections; i++)=0A= + {=0A= + char sname[8];=0A= + unsigned long secptr1 =3D secptr + 40 * i;=0A= + unsigned long vaddr =3D pe_get32 (dll, secptr1 + 12);=0A= + unsigned long vsize =3D pe_get32 (dll, secptr1 + 16);=0A= + unsigned long fptr =3D pe_get32 (dll, secptr1 + 20);=0A= +=0A= + bfd_seek (dll, (file_ptr) secptr1, SEEK_SET);=0A= + bfd_bread (sname, (bfd_size_type) 8, dll);=0A= + if (strcmp (sname, ".text") =3D=3D 0)=0A= + return vaddr;=0A= + }=0A= +=0A= + return 0;=0A= +}=0A= Index: src/gdb/windows-tdep.c=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= RCS file: /cvs/src/src/gdb/windows-tdep.c,v=0A= retrieving revision 1.16=0A= diff -u -p -r1.16 windows-tdep.c=0A= --- src/gdb/windows-tdep.c 5 Jun 2012 13:50:57 -0000 1.16=0A= +++ src/gdb/windows-tdep.c 15 Oct 2012 12:36:49 -0000=0A= @@ -27,6 +27,9 @@=0A= #include "gdbcmd.h"=0A= #include "gdbthread.h"=0A= #include "objfiles.h"=0A= +#include "symfile.h"=0A= +#include "coff-pe-read.h"=0A= +#include "gdb_bfd.h"=0A= =20=0A= struct cmd_list_element *info_w32_cmdlist;=0A= =20=0A= @@ -387,6 +390,9 @@ windows_xfer_shared_library (const char*=0A= struct gdbarch *gdbarch, struct obstack *obstack)=0A= {=0A= char *p;=0A= + struct bfd * dll;=0A= + CORE_ADDR text_offset;=0A= + CORE_ADDR default_text_offset =3D 0x1000;=0A= obstack_grow_str (obstack, "");=0A= }=0A= =20=0A= ------=_NextPart_000_0061_01CDAAEA.C450EF00--