From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26272 invoked by alias); 13 Dec 2012 10:48:15 -0000 Received: (qmail 26262 invoked by uid 22791); 13 Dec 2012 10:48:14 -0000 X-SWARE-Spam-Status: No, hits=-1.7 required=5.0 tests=AWL,BAYES_00,KHOP_THREADED,MIME_QP_LONG_LINE,MSGID_MULTIPLE_AT,TW_BJ,TW_SM X-Spam-Check-By: sourceware.org Received: from mailhost.u-strasbg.fr (HELO mailhost.u-strasbg.fr) (130.79.200.151) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 13 Dec 2012 10:48:09 +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 qBDAlvx9005956 ; Thu, 13 Dec 2012 11:47:58 +0100 (CET) (envelope-from pierre.muller@ics-cnrs.unistra.fr) Received: from mailserver.u-strasbg.fr (ms13.u-strasbg.fr [130.79.204.113]) by md16.u-strasbg.fr (8.14.3/jtpda-5.5pre1) with ESMTP id qBDAlvbC001240 ; Thu, 13 Dec 2012 11:47:57 +0100 (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 qBDAlus0017859 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NO) ; Thu, 13 Dec 2012 11:47:56 +0100 (envelope-from pierre.muller@ics-cnrs.unistra.fr) From: "Pierre Muller" To: "'Joel Brobecker'" Cc: "'asmwarrior'" , "'Eli Zaretskii'" , References: <20121024194517.GK3555@adacore.com> <011901cdb2ab$48076b90$d81642b0$@muller@ics-cnrs.unistra.fr> <20121105171121.GA2972@adacore.com> <50991f5f.8382440a.1100.ffff82abSMTPIN_ADDED@mx.google.com> <509ABA17.30507@redhat.com> <000301cdbd96$f5cd9f10$e168dd30$@muller@ics-cnrs.unistra.fr> <20121122173019.GF9964@adacore.com> <15690.5992342674$1353883881@news.gmane.org> <87624si9ur.fsf@fleche.redhat.com> <001501cdccaf$ad85e9b0$0891bd10$@muller@ics-cnrs.unistra.fr> <20121207071035.GG31477@adacore.com> In-Reply-To: <20121207071035.GG31477@adacore.com> Subject: RE: [RFC-v5] Fix .text section offset for windows DLL (was Calling __stdcall functions in the inferior) Date: Thu, 13 Dec 2012 10:48:00 -0000 Message-ID: <007601cdd91f$51568290$f40387b0$@muller@ics-cnrs.unistra.fr> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0077_01CDD927.B31AEA90" 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-12/txt/msg00434.txt.bz2 This is a multi-part message in MIME format. ------=_NextPart_000_0077_01CDD927.B31AEA90 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-length: 4511 After asmwarrior clarifications that my patch alone didn't cause any crash, I finally committed the patch, after adding the changes suggested by Joel below. The final patch is attached. Concerning Pedro's comments, I will answer to them in his last reply. Thanks to all, Pierre Muller=20=20 > -----Message d'origine----- > De=A0: gdb-patches-owner@sourceware.org [mailto:gdb-patches- > owner@sourceware.org] De la part de Joel Brobecker > Envoy=E9=A0: vendredi 7 d=E9cembre 2012 08:11 > =C0=A0: Pierre Muller > Cc=A0: 'asmwarrior'; 'Eli Zaretskii'; gdb-patches@sourceware.org > Objet=A0: Re: [RFC-v5] Fix .text section offset for windows DLL (was Call= ing > __stdcall functions in the inferior) >=20 > > 2012-11-25 Pierre Muller > > > > * coff-pe-read.h (pe_text_section_offset): Declare new function. > > * coff-pe-read.c (debug_coff_pe_read): New static variable. > > (struct read_pe_section_data): Add section_name field. > > (IMAGE_SCN_CNT_CODE): New macro, if not already defined. > > (IMAGE_SCN_CNT_INITIALIZED_DATA): Ditto. > > (IMAGE_SCN_CNT_UNINITIALIZED_DATA): Ditto. > > (get_pe_section_index): New function. > > (struct pe_sections_info): New type. > > (get_section_vmas): Use new struct pe_sections_info. > > (add_pe_exported_sym): Handle unnamed exported function. > > (add_pe_forwarded_sym): New function. > > (read_pe_truncate_name): Truncate at last dot. > > (pe_as16): New function. > > (read_pe_exported_syms): Use ordinal of function to > > retrieve correct RVA address of function and handle > > forwarded symbol. > > (pe_text_section_offset): New function. > > (show_debug_coff_pe_read): New function. > > (_initialize_coff_pe_read): New function adding > > 'set/show debug coff_pe_read' commands. > > > > * windows-tdep.c (windows_xfer_shared_library): Use > > pe_text_section_offset function instead of possibly wrong > > 0x1000 constant for .text sextion offset. >=20 > Looks good - OK to commit after the following minor corrections > have been applied. For the record, I have tested this patch on > x86-windows against AdaCore's GDB testsuite, no regression. >=20 > Thank you! >=20 > > +/* Get the index of the named section in our own full arrayi. >=20 > Small typo at the end if "array". >=20 > > +get_pe_section_index (const char *section_name, > > + struct read_pe_section_data *sections, > > + int nb_sections) > > +{ > > + int i; > > + for (i =3D 0; i < nb_sections; i++) >=20 > Missing empty line after variable declarations... >=20 > > + DLL_NAME is the internal name of the DLL file, > > + OBJFILE is the objfile struct of DLL_NAME. */ > > + > > + > > +static int > > +add_pe_forwarded_sym (const char *sym_name, const char *forward_dll_name, >=20 > Can you delete the second empty line? >=20 > > + char * last_point =3D strrchr (dll_name, '.'); >=20 > No space between '*' and 'last_point'. >=20 > > + otherix++; > > + section_data =3D xrealloc (section_data, otherix > > + * sizeof (struct read_pe_section_data)); > > + name =3D xstrdup (sec_name); > > + section_data[otherix - 1].section_name =3D name; > > + make_cleanup (xfree, name); > > + section_data[otherix - 1].rva_start =3D vaddr; > > + section_data[otherix - 1].rva_end =3D vaddr + vsize; > > + section_data[otherix - 1].vma_offset =3D 0; > > + if (characteristics & IMAGE_SCN_CNT_CODE) > > + section_data[otherix - 1].ms_type =3D mst_text; > > + else if (characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) > > + section_data[otherix - 1].ms_type =3D mst_data; > > + else if (characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) > > + section_data[otherix - 1].ms_type =3D mst_bss; > > + else > > + section_data[otherix - 1].ms_type =3D mst_unknown; >=20 > A possible suggestion: It seems simpler to increment otherix > at the end rather than at the beginning, and thus have: >=20 > section_data =3D xrealloc (section_data, (otherix + 1) [...]); > [...] > section_data[otherix].rva_end =3D vaddr + vsize; > section_data[otherix].vma_offset =3D 0; > [...] > otherix++; >=20 > > + /* First handle forward cases. */ > > + if ((func_rva >=3D export_rva) > > + && (func_rva < export_rva + export_size)) >=20 > You don't need the extra parentheses... >=20 > -- > Joel ------=_NextPart_000_0077_01CDD927.B31AEA90 Content-Type: application/octet-stream; name="fix-dll-offset-v9.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="fix-dll-offset-v9.patch" Content-length: 29672 2012-12-13 Pierre Muller =0A= =0A= * coff-pe-read.h (pe_text_section_offset): Declare new function.=0A= * coff-pe-read.c (debug_coff_pe_read): New static variable.=0A= (struct read_pe_section_data): Add section_name field.=0A= (IMAGE_SCN_CNT_CODE): New macro, if not already defined.=0A= (IMAGE_SCN_CNT_INITIALIZED_DATA): Ditto.=0A= (IMAGE_SCN_CNT_UNINITIALIZED_DATA): Ditto.=0A= (get_pe_section_index): New function.=0A= (struct pe_sections_info): New type.=0A= (get_section_vmas): Use new struct pe_sections_info.=0A= (add_pe_exported_sym): Handle unnamed exported function.=0A= (add_pe_forwarded_sym): New function.=0A= (read_pe_truncate_name): Truncate at last dot.=0A= (pe_as16): New function.=0A= (read_pe_exported_syms): Use ordinal of function to=0A= retrieve correct RVA address of function and handle=0A= forwarded symbol.=0A= (pe_text_section_offset): New function.=0A= (show_debug_coff_pe_read): New function.=0A= (_initialize_coff_pe_read): New function adding=0A= 'set/show debug coff_pe_read' commands.=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= Index: 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= --- coff-pe-read.h 4 Jan 2012 08:17:00 -0000 1.11=0A= +++ coff-pe-read.h 13 Dec 2012 10:41:57 -0000=0A= @@ -23,9 +23,14 @@=0A= #define COFF_PE_READ_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= +/* Extract from ABFD the offset of the .text section.=0A= + Returns default value 0x1000 if information is not found. */=0A= +extern CORE_ADDR pe_text_section_offset (struct bfd *abfd);=0A= +=0A= #endif /* !defined (COFF_PE_READ_H) */=0A= Index: 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.18=0A= diff -u -p -r1.18 coff-pe-read.c=0A= --- coff-pe-read.c 7 Nov 2012 20:10:13 -0000 1.18=0A= +++ coff-pe-read.c 13 Dec 2012 10:41:57 -0000=0A= @@ -28,12 +28,23 @@=0A= #include "bfd.h"=0A= #include "gdbtypes.h"=0A= =20=0A= +#include "command.h"=0A= +#include "gdbcmd.h"=0A= #include "symtab.h"=0A= #include "symfile.h"=0A= #include "objfiles.h"=0A= +#include "common/common-utils.h"=0A= +=0A= +#include =0A= =20=0A= /* Internal section information */=0A= =20=0A= +/* Coff PE read debugging flag:=0A= + default value is 0,=0A= + value 1 outputs problems encountered while parsing PE file,=0A= + value above 1 also lists all generated minimal symbols. */=0A= +static unsigned int debug_coff_pe_read;=0A= +=0A= struct read_pe_section_data=0A= {=0A= CORE_ADDR vma_offset; /* Offset to loaded address of section. */=0A= @@ -41,8 +52,18 @@ struct read_pe_section_data=0A= unsigned long rva_end; /* End offset within the pe. */=0A= enum minimal_symbol_type ms_type; /* Type to assign symbols in=0A= section. */=0A= + char *section_name; /* Recorded section name. */=0A= };=0A= =20=0A= +#ifndef IMAGE_SCN_CNT_CODE=0A= +# define IMAGE_SCN_CNT_CODE 0x20=0A= +#endif=0A= +#ifndef IMAGE_SCN_CNT_INITIALIZED_DATA=0A= +# define IMAGE_SCN_CNT_INITIALIZED_DATA 0x40=0A= +#endif=0A= +#ifndef IMAGE_SCN_CNT_UNINITIALIZED_DATA=0A= +# define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x80=0A= +#endif=0A= #define PE_SECTION_INDEX_TEXT 0=0A= #define PE_SECTION_INDEX_DATA 1=0A= #define PE_SECTION_INDEX_BSS 2=0A= @@ -77,13 +98,41 @@ read_pe_section_index (const char *secti=0A= }=0A= }=0A= =20=0A= +/* Get the index of the named section in our own full arrayi.=0A= + text, data and bss in that order. Return PE_SECTION_INDEX_INVALID=0A= + if passed an unrecognised section name. */=0A= +=0A= +static int=0A= +get_pe_section_index (const char *section_name,=0A= + struct read_pe_section_data *sections,=0A= + int nb_sections)=0A= +{=0A= + int i;=0A= +=0A= + for (i =3D 0; i < nb_sections; i++)=0A= + if (strcmp (sections[i].section_name, section_name) =3D=3D 0)=0A= + return i;=0A= + return PE_SECTION_INDEX_INVALID;=0A= +}=0A= +=0A= +/* Structure used by get_section_vmas function below=0A= + to access section_data array and the size of the array=0A= + stored in nb_sections field. */=0A= +struct pe_sections_info=0A= +{=0A= + int nb_sections;=0A= + struct read_pe_section_data *sections;=0A= +};=0A= +=0A= /* Record the virtual memory address of a section. */=0A= =20=0A= static void=0A= get_section_vmas (bfd *abfd, asection *sectp, void *context)=0A= {=0A= - struct read_pe_section_data *sections =3D context;=0A= - int sectix =3D read_pe_section_index (sectp->name);=0A= + struct pe_sections_info *data =3D context;=0A= + struct read_pe_section_data *sections =3D data->sections;=0A= + int sectix =3D get_pe_section_index (sectp->name, sections,=0A= + data->nb_sections);=0A= =20=0A= if (sectix !=3D PE_SECTION_INDEX_INVALID)=0A= {=0A= @@ -95,58 +144,147 @@ get_section_vmas (bfd *abfd, asection *s=0A= }=0A= }=0A= =0C=0A= -/* Create a minimal symbol entry for an exported symbol. */=0A= +/* Create a minimal symbol entry for an exported symbol.=0A= + SYM_NAME contains the exported name or NULL if exported by ordinal,=0A= + FUNC_RVA contains the Relative Virtual Address of the symbol,=0A= + ORDINAL is the ordinal index value of the symbol,=0A= + SECTION_DATA contains information about the section in which the=0A= + symbol is declared,=0A= + DLL_NAME is the internal name of the DLL file,=0A= + OBJFILE is the objfile struct of DLL_NAME. */=0A= =20=0A= static void=0A= -add_pe_exported_sym (char *sym_name,=0A= +add_pe_exported_sym (const char *sym_name,=0A= unsigned long func_rva,=0A= + int ordinal,=0A= const struct read_pe_section_data *section_data,=0A= const char *dll_name, struct objfile *objfile)=0A= {=0A= + char *qualified_name, *bare_name;=0A= /* Add the stored offset to get the loaded address of the symbol. */=0A= -=0A= CORE_ADDR vma =3D func_rva + section_data->vma_offset;=0A= -=0A= - char *qualified_name =3D 0;=0A= int dll_name_len =3D strlen (dll_name);=0A= =20=0A= /* Generate a (hopefully unique) qualified name using the first part=0A= of the dll name, e.g. KERNEL32!AddAtomA. This matches the style=0A= used by windbg from the "Microsoft Debugging Tools for Windows". */= =0A= =20=0A= - qualified_name =3D xmalloc (dll_name_len + strlen (sym_name) + 2);=0A= + if (sym_name =3D=3D NULL || *sym_name =3D=3D '\0')=0A= + bare_name =3D xstrprintf ("#%d", ordinal);=0A= + else=0A= + bare_name =3D xstrdup (sym_name);=0A= +=0A= + qualified_name =3D xstrprintf ("%s!%s", dll_name, bare_name);=0A= =20=0A= - strncpy (qualified_name, dll_name, dll_name_len);=0A= - qualified_name[dll_name_len] =3D '!';=0A= - strcpy (qualified_name + dll_name_len + 1, sym_name);=0A= + if ((section_data->ms_type =3D=3D mst_unknown) && debug_coff_pe_read)=0A= + fprintf_unfiltered (gdb_stdlog , _("Unknown section type for \"%s\""= =0A= + " for entry \"%s\" in dll \"%s\"\n"),=0A= + section_data->section_name, sym_name, dll_name);=0A= =20=0A= - prim_record_minimal_symbol (qualified_name,=0A= - vma, section_data->ms_type, objfile);=0A= + prim_record_minimal_symbol (qualified_name, vma,=0A= + section_data->ms_type, objfile);=0A= =20=0A= + /* Enter the plain name as well, which might not be unique. */=0A= + prim_record_minimal_symbol (bare_name, vma, section_data->ms_type, objfi= le);=0A= + if (debug_coff_pe_read > 1)=0A= + fprintf_unfiltered (gdb_stdlog, _("Adding exported symbol \"%s\""=0A= + " in dll \"%s\"\n"), sym_name, dll_name);=0A= xfree (qualified_name);=0A= + xfree (bare_name);=0A= +}=0A= +=0A= +/* Create a minimal symbol entry for an exported forward symbol.=0A= + Return 1 if the forwarded function was found 0 otherwise.=0A= + SYM_NAME contains the exported name or NULL if exported by ordinal,=0A= + FORWARD_DLL_NAME is the name of the DLL in which the target symobl resi= des,=0A= + FORWARD_FUNC_NAME is the name of the target symbol in that DLL,=0A= + ORDINAL is the ordinal index value of the symbol,=0A= + DLL_NAME is the internal name of the DLL file,=0A= + OBJFILE is the objfile struct of DLL_NAME. */=0A= +=0A= +static int=0A= +add_pe_forwarded_sym (const char *sym_name, const char *forward_dll_name,= =0A= + const char *forward_func_name, int ordinal,=0A= + const char *dll_name, struct objfile *objfile)=0A= +{=0A= + CORE_ADDR vma;=0A= + struct objfile *forward_objfile;=0A= + struct minimal_symbol *msymbol;=0A= + short section;=0A= + enum minimal_symbol_type msymtype;=0A= + int dll_name_len =3D strlen (dll_name);=0A= + char *qualified_name, *bare_name;=0A= + int forward_dll_name_len =3D strlen (forward_dll_name);=0A= + int forward_func_name_len =3D strlen (forward_func_name);=0A= + int forward_len =3D forward_dll_name_len + forward_func_name_len + 2;=0A= + char *forward_qualified_name =3D alloca (forward_len);=0A= +=0A= + xsnprintf (forward_qualified_name, forward_len, "%s!%s", forward_dll_nam= e,=0A= + forward_func_name);=0A= +=0A= +=0A= + msymbol =3D lookup_minimal_symbol_and_objfile (forward_qualified_name,= =0A= + &forward_objfile);=0A= +=0A= + if (!msymbol)=0A= + {=0A= + int i;=0A= +=0A= + for (i =3D 0; i < forward_dll_name_len; i++)=0A= + forward_qualified_name[i] =3D tolower (forward_qualified_name[i]);=0A= + msymbol =3D lookup_minimal_symbol_and_objfile (forward_qualified_nam= e,=0A= + &forward_objfile);=0A= + }=0A= +=0A= + if (!msymbol)=0A= + {=0A= + if (debug_coff_pe_read)=0A= + fprintf_unfiltered (gdb_stdlog, _("Unable to find function \"%s\" in"=0A= + " dll \"%s\", forward of \"%s\" in dll \"%s\"\n"),=0A= + forward_func_name, forward_dll_name, sym_name,=0A= + dll_name);=0A= + return 0;=0A= + }=0A= +=0A= + if (debug_coff_pe_read > 1)=0A= + fprintf_unfiltered (gdb_stdlog, _("Adding forwarded exported symbol"= =0A= + " \"%s\" in dll \"%s\", pointing to \"%s\"\n"),=0A= + sym_name, dll_name, forward_qualified_name);=0A= +=0A= + vma =3D SYMBOL_VALUE_ADDRESS (msymbol);=0A= + section =3D SYMBOL_SECTION (msymbol);=0A= + msymtype =3D MSYMBOL_TYPE (msymbol);=0A= +=0A= + /* Generate a (hopefully unique) qualified name using the first part=0A= + of the dll name, e.g. KERNEL32!AddAtomA. This matches the style=0A= + used by windbg from the "Microsoft Debugging Tools for Windows". */= =0A= +=0A= + if (sym_name =3D=3D NULL || *sym_name =3D=3D '\0')=0A= + bare_name =3D xstrprintf ("#%d", ordinal);=0A= + else=0A= + bare_name =3D xstrdup (sym_name);=0A= +=0A= + qualified_name =3D xstrprintf ("%s!%s", dll_name, bare_name);=0A= +=0A= + prim_record_minimal_symbol (qualified_name, vma, msymtype, objfile);=0A= =20=0A= /* Enter the plain name as well, which might not be unique. */=0A= - prim_record_minimal_symbol (sym_name, vma,=20=0A= - section_data->ms_type, objfile);=0A= + prim_record_minimal_symbol (bare_name, vma, msymtype, objfile);=0A= + xfree (qualified_name);=0A= + xfree (bare_name);=0A= +=0A= + return 1;=0A= }=0A= =20=0A= -/* Truncate a dll_name at the first dot character. */=0A= +/* Truncate a dll_name at the last dot character. */=0A= =20=0A= static void=0A= read_pe_truncate_name (char *dll_name)=0A= {=0A= - while (*dll_name)=0A= - {=0A= - if ((*dll_name) =3D=3D '.')=0A= - {=0A= - *dll_name =3D '\0'; /* truncates and causes loop exit. */=0A= - }=0A= + char *last_point =3D strrchr (dll_name, '.');=0A= =20=0A= - else=0A= - {=0A= - ++dll_name;=0A= - }=0A= - }=0A= + if (last_point !=3D NULL)=0A= + *last_point =3D '\0';=0A= }=0A= =0C=0A= /* Low-level support functions, direct from the ld module pe-dll.c. */=0A= @@ -171,6 +309,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= @@ -186,35 +332,53 @@ void=0A= read_pe_exported_syms (struct objfile *objfile)=0A= {=0A= bfd *dll =3D objfile->obfd;=0A= + unsigned long nbnormal, nbforward;=0A= unsigned long pe_header_offset, opthdr_ofs, num_entries, i;=0A= + unsigned long export_opthdrrva, export_opthdrsize;=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= + char *dll_name =3D (char *) dll->filename;=0A= + int otherix =3D PE_SECTION_TABLE_SIZE;=0A= + int exportix =3D -1;=0A= int is_pe64 =3D 0;=0A= int is_pe32 =3D 0;=0A= =20=0A= /* Array elements are for text, data and bss in that order=0A= - Initialization with start_rva > end_rva guarantees that=0A= + Initialization with RVA_START > RVA_END guarantees that=0A= unused sections won't be matched. */=0A= - struct read_pe_section_data section_data[PE_SECTION_TABLE_SIZE]=0A= - =3D { {0, 1, 0, mst_text},=0A= - {0, 1, 0, mst_data},=0A= - {0, 1, 0, mst_bss}=0A= - };=0A= + struct read_pe_section_data *section_data;=0A= + struct pe_sections_info pe_sections_info;=0A= =20=0A= - struct cleanup *back_to =3D 0;=0A= + struct cleanup *back_to =3D make_cleanup (null_cleanup, 0);=0A= =20=0A= char const *target =3D bfd_get_target (objfile->obfd);=0A= =20=0A= + section_data =3D xzalloc (PE_SECTION_TABLE_SIZE=0A= + * sizeof (struct read_pe_section_data));=0A= +=0A= + make_cleanup (free_current_contents, §ion_data);=0A= +=0A= + for (i=3D0; i < PE_SECTION_TABLE_SIZE; i++)=0A= + {=0A= + section_data[i].vma_offset =3D 0;=0A= + section_data[i].rva_start =3D 1;=0A= + section_data[i].rva_end =3D 0;=0A= + };=0A= + section_data[PE_SECTION_INDEX_TEXT].ms_type =3D mst_text;=0A= + section_data[PE_SECTION_INDEX_TEXT].section_name =3D ".text";=0A= + section_data[PE_SECTION_INDEX_DATA].ms_type =3D mst_data;=0A= + section_data[PE_SECTION_INDEX_DATA].section_name =3D ".data";=0A= + section_data[PE_SECTION_INDEX_BSS].ms_type =3D mst_bss;=0A= + section_data[PE_SECTION_INDEX_BSS].section_name =3D ".bss";=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= @@ -235,21 +399,21 @@ read_pe_exported_syms (struct objfile *o=0A= {=0A= return;=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= + export_opthdrrva =3D pe_get32 (dll, opthdr_ofs + 112);=0A= + export_opthdrsize =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= + export_opthdrrva =3D pe_get32 (dll, opthdr_ofs + 96);=0A= + export_opthdrsize =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= + export_size =3D 0;=0A= =20=0A= /* Get the rva and size of the export section. */=0A= for (i =3D 0; i < nsections; i++)=0A= @@ -261,17 +425,31 @@ read_pe_exported_syms (struct objfile *o=0A= unsigned long fptr =3D pe_get32 (dll, secptr1 + 20);=0A= =20=0A= bfd_seek (dll, (file_ptr) secptr1, SEEK_SET);=0A= - bfd_bread (sname, (bfd_size_type) 8, dll);=0A= + bfd_bread (sname, (bfd_size_type) sizeof (sname), dll);=0A= =20=0A= - if (vaddr <=3D export_rva && vaddr + vsize > export_rva)=0A= + if ((strcmp (sname, ".edata") =3D=3D 0)=0A= + || (vaddr <=3D export_opthdrrva && export_opthdrrva < vaddr + vsize))= =0A= {=0A= - expptr =3D fptr + (export_rva - vaddr);=0A= - if (export_rva + export_size > vaddr + vsize)=0A= - export_size =3D vsize - (export_rva - vaddr);=0A= + if (strcmp (sname, ".edata") !=3D 0)=0A= + {=0A= + if (debug_coff_pe_read)=0A= + fprintf_unfiltered (gdb_stdlog, _("Export RVA for dll "=0A= + "\"%s\" is in section \"%s\"\n"),=0A= + dll_name, sname);=0A= + }=0A= + else if (export_opthdrrva !=3D vaddr && debug_coff_pe_read)=0A= + fprintf_unfiltered (gdb_stdlog, _("Wrong value of export RVA"=0A= + " for dll \"%s\": 0x%lx instead of 0x%lx\n"),=0A= + dll_name, export_opthdrrva, vaddr);=0A= + expptr =3D fptr + (export_opthdrrva - vaddr);=0A= + exportix =3D i;=0A= break;=0A= }=0A= }=0A= =20=0A= + export_rva =3D export_opthdrrva;=0A= + export_size =3D export_opthdrsize;=0A= +=0A= if (export_size =3D=3D 0)=0A= {=0A= /* Empty export table. */=0A= @@ -285,10 +463,11 @@ read_pe_exported_syms (struct objfile *o=0A= unsigned long secptr1 =3D secptr + 40 * i;=0A= unsigned long vsize =3D pe_get32 (dll, secptr1 + 8);=0A= unsigned long vaddr =3D pe_get32 (dll, secptr1 + 12);=0A= + unsigned long characteristics =3D pe_get32 (dll, secptr1 + 36);=0A= char sec_name[9];=0A= int sectix;=0A= =20=0A= - sec_name[8] =3D '\0';=0A= + memset (sec_name, 0, sizeof (sec_name));=0A= bfd_seek (dll, (file_ptr) secptr1 + 0, SEEK_SET);=0A= bfd_bread (sec_name, (bfd_size_type) 8, dll);=0A= =20=0A= @@ -299,10 +478,32 @@ read_pe_exported_syms (struct objfile *o=0A= section_data[sectix].rva_start =3D vaddr;=0A= section_data[sectix].rva_end =3D vaddr + vsize;=0A= }=0A= + else=0A= + {=0A= + char *name;=0A= +=0A= + section_data =3D xrealloc (section_data, (otherix + 1)=0A= + * sizeof (struct read_pe_section_data));=0A= + name =3D xstrdup (sec_name);=0A= + section_data[otherix].section_name =3D name;=0A= + make_cleanup (xfree, name);=0A= + section_data[otherix].rva_start =3D vaddr;=0A= + section_data[otherix].rva_end =3D vaddr + vsize;=0A= + section_data[otherix].vma_offset =3D 0;=0A= + if (characteristics & IMAGE_SCN_CNT_CODE)=0A= + section_data[otherix].ms_type =3D mst_text;=0A= + else if (characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)=0A= + section_data[otherix].ms_type =3D mst_data;=0A= + else if (characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)=0A= + section_data[otherix].ms_type =3D mst_bss;=0A= + else=0A= + section_data[otherix].ms_type =3D mst_unknown;=0A= + otherix++;=0A= + }=0A= }=0A= =20=0A= expdata =3D (unsigned char *) xmalloc (export_size);=0A= - back_to =3D make_cleanup (xfree, expdata);=0A= + make_cleanup (xfree, expdata);=0A= =20=0A= bfd_seek (dll, (file_ptr) expptr, SEEK_SET);=0A= bfd_bread (expdata, (bfd_size_type) export_size, dll);=0A= @@ -317,12 +518,15 @@ read_pe_exported_syms (struct objfile *o=0A= /* Use internal dll name instead of full pathname. */=0A= dll_name =3D pe_as32 (expdata + 12) + erva;=0A= =20=0A= - bfd_map_over_sections (dll, get_section_vmas, section_data);=0A= + pe_sections_info.nb_sections =3D otherix;=0A= + pe_sections_info.sections =3D section_data;=0A= +=0A= + bfd_map_over_sections (dll, get_section_vmas, &pe_sections_info);=0A= =20=0A= /* Adjust the vma_offsets in case this PE got relocated. This=0A= assumes that *all* sections share the same relocation offset=0A= as the text section. */=0A= - for (i =3D 0; i < PE_SECTION_TABLE_SIZE; i++)=0A= + for (i =3D 0; i < otherix; i++)=0A= {=0A= section_data[i].vma_offset=0A= +=3D ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));=0A= @@ -332,31 +536,184 @@ read_pe_exported_syms (struct objfile *o=0A= lower case for convenience on Windows. */=0A= read_pe_truncate_name (dll_name);=0A= =20=0A= + if (debug_coff_pe_read)=0A= + fprintf_unfiltered (gdb_stdlog, _("DLL \"%s\" has %ld export entries,"= =0A= + " base=3D%ld\n"), dll_name, nexp, ordbase);=0A= + nbforward =3D 0;=0A= + nbnormal =3D 0;=0A= /* Iterate through the list of symbols. */=0A= for (i =3D 0; i < nexp; i++)=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= +=0A= + /* First handle forward cases. */=0A= + if (func_rva >=3D export_rva && func_rva < export_rva + export_size)= =0A= + {=0A= + char *forward_name =3D (char *) (erva + func_rva);=0A= + char *funcname =3D (char *) (erva + name_rva);=0A= + char *forward_dll_name =3D forward_name;=0A= + char *forward_func_name =3D forward_name;=0A= + char *sep =3D strrchr (forward_name, '.');=0A= +=0A= + if (sep)=0A= + {=0A= + int len =3D (int) (sep - forward_name);=0A= =20=0A= - for (sectix =3D 0; sectix < PE_SECTION_TABLE_SIZE; ++sectix)=0A= + forward_dll_name =3D alloca (len + 1);=0A= + strncpy (forward_dll_name, forward_name, len);=0A= + forward_dll_name[len] =3D '\0';=0A= + forward_func_name =3D ++sep;=0A= + }=0A= + if (add_pe_forwarded_sym (funcname, forward_dll_name,=0A= + forward_func_name, ordinal,=0A= + dll_name, objfile) !=3D 0)=0A= + ++nbforward;=0A= + continue;=0A= + }=0A= +=0A= + for (sectix =3D 0; sectix < otherix; ++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= + func_rva, ordinal,=0A= section_data + sectix, dll_name, objfile);=0A= + ++nbnormal;=0A= break;=0A= }=0A= }=0A= + if (!section_found)=0A= + {=0A= + char *funcname =3D (char *) (erva + name_rva);=0A= +=0A= + if (name_rva =3D=3D 0)=0A= + {=0A= + add_pe_exported_sym (NULL, func_rva, ordinal,=0A= + section_data, dll_name, objfile);=0A= + ++nbnormal;=0A= + }=0A= + else if (debug_coff_pe_read)=0A= + fprintf_unfiltered (gdb_stdlog, _("Export name \"%s\" ord. %lu,"=0A= + " RVA 0x%lx in dll \"%s\" not handled\n"),=0A= + funcname, ordinal, func_rva, dll_name);=0A= + }=0A= }=0A= =20=0A= - /* Discard expdata. */=0A= + if (debug_coff_pe_read)=0A= + fprintf_unfiltered (gdb_stdlog, _("Finished reading \"%s\", exports %l= d,"=0A= + " forwards %ld, total %ld/%ld.\n"), dll_name, nbnormal,=0A= + nbforward, nbnormal + nbforward, nexp);=0A= + /* Discard expdata and section_data. */=0A= do_cleanups (back_to);=0A= }=0A= +=0A= +/* Extract from ABFD the offset of the .text section.=0A= + This offset is mainly related to the offset within the file.=0A= + The value was previously expected to be 0x1000 for all files,=0A= + but some Windows OS core DLLs seem to use 0x10000 section alignement=0A= + which modified the return value of that function.=0A= + Still return default 0x1000 value if ABFD is NULL or=0A= + if '.text' section is not found, but that should not happen... */=0A= +=0A= +#define DEFAULT_COFF_PE_TEXT_SECTION_OFFSET 0x1000=0A= +=0A= +CORE_ADDR=0A= +pe_text_section_offset (struct bfd *abfd)=0A= +=0A= +{=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= + char const *target;=0A= +=0A= + if (!abfd)=0A= + return DEFAULT_COFF_PE_TEXT_SECTION_OFFSET;=0A= +=0A= + target =3D bfd_get_target (abfd);=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 DEFAULT_COFF_PE_TEXT_SECTION_OFFSET;=0A= + }=0A= +=0A= + /* Get pe_header, optional header and numbers of sections. */=0A= + pe_header_offset =3D pe_get32 (abfd, 0x3c);=0A= + opthdr_ofs =3D pe_header_offset + 4 + 20;=0A= + nsections =3D pe_get16 (abfd, pe_header_offset + 4 + 2);=0A= + secptr =3D (pe_header_offset + 4 + 20 +=0A= + pe_get16 (abfd, pe_header_offset + 4 + 16));=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 (abfd, secptr1 + 12);=0A= +=0A= + bfd_seek (abfd, (file_ptr) secptr1, SEEK_SET);=0A= + bfd_bread (sname, (bfd_size_type) 8, abfd);=0A= + if (strcmp (sname, ".text") =3D=3D 0)=0A= + return vaddr;=0A= + }=0A= +=0A= + return DEFAULT_COFF_PE_TEXT_SECTION_OFFSET;=0A= +}=0A= +=0A= +/* Implements "show debug coff_pe_read" command. */=0A= +=0A= +static void=0A= +show_debug_coff_pe_read (struct ui_file *file, int from_tty,=0A= + struct cmd_list_element *c, const char *value)=0A= +{=0A= + fprintf_filtered (file, _("Coff PE read debugging is %s.\n"), value);=0A= +}=0A= +=0A= +/* Provide a prototype to silence -Wmissing-prototypes. */=0A= +=0A= +void _initialize_coff_pe_read (void);=0A= +=0A= +/* Adds "Set/show debug coff_pe_read" commands. */=0A= +=0A= +void=0A= +_initialize_coff_pe_read (void)=0A= +{=0A= + add_setshow_uinteger_cmd ("coff_pe_read", class_maintenance,=0A= + &debug_coff_pe_read,=0A= + _("Set coff PE read debugging."),=0A= + _("Show coff PE read debugging."),=0A= + _("When set, debugging messages for coff reading "=0A= + "of exported symbols are displayed."),=0A= + NULL, show_debug_coff_pe_read,=0A= + &setdebuglist, &showdebuglist);=0A= +}=0A= Index: 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.17=0A= diff -u -p -r1.17 windows-tdep.c=0A= --- windows-tdep.c 9 Nov 2012 19:58:02 -0000 1.17=0A= +++ windows-tdep.c 13 Dec 2012 10:41:57 -0000=0A= @@ -27,6 +27,10 @@=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= +#include "complaints.h"=0A= =20=0A= struct cmd_list_element *info_w32_cmdlist;=0A= =20=0A= @@ -387,15 +391,21 @@ 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= +=0A= obstack_grow_str (obstack, "");=0A= }=0A= =20=0A= ------=_NextPart_000_0077_01CDD927.B31AEA90--