From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5183 invoked by alias); 6 Nov 2012 14:31:56 -0000 Received: (qmail 5172 invoked by uid 22791); 6 Nov 2012 14:31:55 -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 X-Spam-Check-By: sourceware.org Received: from mailhost.u-strasbg.fr (HELO mailhost.u-strasbg.fr) (130.79.200.156) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 06 Nov 2012 14:31:50 +0000 Received: from md14.u-strasbg.fr (md14.u-strasbg.fr [130.79.200.249]) by mailhost.u-strasbg.fr (8.14.3/jtpda-5.5pre1) with ESMTP id qA6EVh4A030123 ; Tue, 6 Nov 2012 15:31:44 +0100 (CET) (envelope-from pierre.muller@ics-cnrs.unistra.fr) Received: from mailserver.u-strasbg.fr (ms14.u-strasbg.fr [130.79.204.114]) by md14.u-strasbg.fr (8.14.3/jtpda-5.5pre1) with ESMTP id qA6EVhjt016254 ; Tue, 6 Nov 2012 15:31:43 +0100 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 qA6EVgXJ009240 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NO) ; Tue, 6 Nov 2012 15:31:42 +0100 (envelope-from pierre.muller@ics-cnrs.unistra.fr) From: "Pierre Muller" To: "'Joel Brobecker'" Cc: References: <83a9vs89r9.fsf@gnu.org> <201210120953.q9C9rqfu020865@glazunov.sibelius.xs4all.nl> <834nm07z0s.fsf@gnu.org> <5077FEB9.4030304@redhat.com> <83y5jb7rfe.fsf@gnu.org> <006001cdaada$00c81f00$02585d00$@muller@ics-cnrs.unistra.fr> <20121024194517.GK3555@adacore.com> <011901cdb2ab$48076b90$d81642b0$@muller@ics-cnrs.unistra.fr> <20121105171121.GA2972@adacore.com> In-Reply-To: <20121105171121.GA2972@adacore.com> Subject: [RFC-v2] Fix .text section offset for windows DLL (was Calling __stdcall functions in the inferior) Date: Tue, 06 Nov 2012 14:31:00 -0000 Message-ID: <000001cdbc2b$7005db20$50119160$@muller@ics-cnrs.unistra.fr> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0001_01CDBC33.D1CA4320" 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-11/txt/msg00111.txt.bz2 This is a multi-part message in MIME format. ------=_NextPart_000_0001_01CDBC33.D1CA4320 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-length: 1522 I wrote a new version of the patch that tries to implement most of the things we talked about. It works quite nicely on my windows 7 64-bit using cygwin, mingw32 or a cross-built mingw64 binary. Interestingly, it seems that the mingw64 binary is not really affected by this issue because the 64-bit system DLLs do have a section offset of 0x1000 for .text section, while the 32-bit DLLs have 0x10000. Pierre Muller 2012-11-06 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. (pe_as16): New function. (IMAGE_SCN_CNT_CODE): New macro, if not already defined. (IMAGE_SCN_CNT_INITIALIZED_DATA): Ditto. (IMAGE_SCN_CNT_UNINITIALIZED_DATA): Ditto. (add_pe_exported_sym): Handle unnamed exported function. (add_pe_forwarded_sym): 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. ------=_NextPart_000_0001_01CDBC33.D1CA4320 Content-Type: application/octet-stream; name="fix-dll-offset-v3.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="fix-dll-offset-v3.patch" Content-length: 25664 2012-11-06 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= (pe_as16): New function.=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= (add_pe_exported_sym): Handle unnamed exported function.=0A= (add_pe_forwarded_sym): 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= =0A= =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 6 Nov 2012 13:37:01 -0000=0A= @@ -21,11 +21,17 @@=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= +/* Extract for 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.17=0A= diff -u -p -r1.17 coff-pe-read.c=0A= --- coff-pe-read.c 4 Jan 2012 08:17:00 -0000 1.17=0A= +++ coff-pe-read.c 6 Nov 2012 13:37:01 -0000=0A= @@ -23,16 +23,26 @@=0A= =20=0A= #include "coff-pe-read.h"=0A= =20=0A= +#include =0A= #include "defs.h"=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= =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= @@ -40,8 +50,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= @@ -99,9 +119,11 @@ get_section_vmas (bfd *abfd, asection *s=0A= static void=0A= add_pe_exported_sym (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 ordinal_name[10];=0A= /* Add the stored offset to get the loaded address of the symbol. */=0A= =20=0A= CORE_ADDR vma =3D func_rva + section_data->vma_offset;=0A= @@ -113,39 +135,130 @@ add_pe_exported_sym (char *sym_name,=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= + if (*sym_name =3D=3D '\0')=0A= + {=0A= + xsnprintf (ordinal_name, sizeof (ordinal_name), "#%d", ordinal);=0A= + sym_name =3D ordinal_name;=0A= + }=0A= +=0A= qualified_name =3D xmalloc (dll_name_len + strlen (sym_name) + 2);=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= =20=0A= + if ((section_data->ms_type =3D=3D mst_unknown) && debug_coff_pe_read)=0A= + printf_filtered (_("Unknown section type for \"%s\" for entry \"%s\" \= =0A= +in dll \"%s\"\n"),=0A= + section_data->section_name, sym_name, dll_name);=0A= +=0A= prim_record_minimal_symbol (qualified_name,=0A= vma, section_data->ms_type, objfile);=0A= =20=0A= xfree (qualified_name);=0A= =20=0A= /* Enter the plain name as well, which might not be unique. */=0A= - prim_record_minimal_symbol (sym_name, vma,=20=0A= + prim_record_minimal_symbol (sym_name, vma,=0A= section_data->ms_type, objfile);=0A= + if (debug_coff_pe_read > 1)=0A= + printf_filtered (_("Adding exported symbol \"%s\" in dll \"%s\"\n"),= =0A= + sym_name, dll_name);=0A= }=0A= =20=0A= -/* Truncate a dll_name at the first dot character. */=0A= +/* Create a minimal symbol entry for an exported forward symbol.=0A= + Returns 1 if the forwarded function was found 0 otherwise. */=0A= =20=0A= -static void=0A= -read_pe_truncate_name (char *dll_name)=0A= +static int=0A= +add_pe_forwarded_sym (char *sym_name, char *forward_dll_name,=0A= + char *forward_func_name, int ordinal,=0A= + const char *dll_name, struct objfile *objfile)=0A= {=0A= - while (*dll_name)=0A= + char ordinal_name[10];=0A= + int forward_dll_name_len =3D strlen (forward_dll_name);=0A= + int forward_func_name_len =3D strlen (forward_func_name);=0A= + CORE_ADDR vma;=0A= + struct objfile *forward_objfile;=0A= + struct minimal_symbol *msymbol;=0A= + short section;=0A= + enum minimal_symbol_type msymtype;=0A= + char *qualified_name =3D 0;=0A= + int dll_name_len =3D strlen (dll_name);=0A= + char *forward_minimal_name =3D xmalloc (forward_dll_name_len +=0A= + forward_func_name_len + 2);=0A= +=0A= + strncpy (forward_minimal_name, forward_dll_name, forward_dll_name_len);= =0A= + forward_minimal_name[forward_dll_name_len] =3D '!';=0A= + strcpy (forward_minimal_name + forward_dll_name_len + 1, forward_func_na= me);=0A= +=0A= +=0A= + msymbol =3D lookup_minimal_symbol_and_objfile (forward_minimal_name,=0A= + &forward_objfile);=0A= +=0A= + if (!msymbol)=0A= {=0A= - if ((*dll_name) =3D=3D '.')=0A= - {=0A= - *dll_name =3D '\0'; /* truncates and causes loop exit. */=0A= - }=0A= + int i;=0A= + for (i =3D 0; i < forward_dll_name_len; i++)=0A= + forward_minimal_name[i] =3D tolower (forward_minimal_name[i]);=0A= + msymbol =3D lookup_minimal_symbol_and_objfile (forward_minimal_name,= =0A= + &forward_objfile);=0A= + }=0A= =20=0A= - else=0A= - {=0A= - ++dll_name;=0A= - }=0A= + if (debug_coff_pe_read > 1)=0A= + printf_filtered (_("Adding forwarded exported symbol \"%s\" "=0A= + "in dll \"%s\", pointing to \"%s\"\n"),=0A= + sym_name, dll_name, forward_minimal_name);=0A= +=0A= + xfree (forward_minimal_name);=0A= +=0A= + if (!msymbol)=0A= + {=0A= + if (debug_coff_pe_read)=0A= + printf_filtered (_("Unable to find function \"%s\" in dll \"%s\" "=0A= + ", 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= + 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 '\0')=0A= + {=0A= + xsnprintf (ordinal_name, sizeof (ordinal_name), "#%d", ordinal);=0A= + sym_name =3D ordinal_name;=0A= + }=0A= +=0A= + qualified_name =3D xmalloc (dll_name_len + strlen (sym_name) + 2);=0A= +=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= +=0A= + prim_record_minimal_symbol (qualified_name,=0A= + vma, msymtype, objfile);=0A= +=0A= + xfree (qualified_name);=0A= +=0A= + /* Enter the plain name as well, which might not be unique. */=0A= + prim_record_minimal_symbol (sym_name, vma,=0A= + msymtype, objfile);=0A= + return 1;=0A= +}=0A= +=0A= +/* Truncate a dll_name at the last dot character. */=0A= +=0A= +static void=0A= +read_pe_truncate_name (char *dll_name)=0A= +{=0A= + char * last_point =3D strrchr (dll_name, '.');=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= @@ -170,6 +283,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= @@ -185,35 +306,50 @@ 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= =20=0A= struct cleanup *back_to =3D 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= + 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= @@ -234,21 +370,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= @@ -262,15 +398,30 @@ read_pe_exported_syms (struct objfile *o=0A= bfd_seek (dll, (file_ptr) secptr1, SEEK_SET);=0A= bfd_bread (sname, (bfd_size_type) 8, 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)=0A= + && (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= + printf_filtered (_("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= + printf_filtered (_("Wrong value of export RVA for dll \"%s\": "=0A= + "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= @@ -284,6 +435,7 @@ 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= @@ -298,6 +450,24 @@ 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= + otherix++;=0A= + section_data =3D xrealloc (section_data, otherix=0A= + * sizeof (struct read_pe_section_data));=0A= + section_data[otherix - 1].section_name =3D xstrdup (sec_name);=0A= + section_data[otherix - 1].rva_start =3D vaddr;=0A= + section_data[otherix - 1].rva_end =3D vaddr + vsize;=0A= + section_data[otherix - 1].vma_offset =3D 0;=0A= + if (characteristics & IMAGE_SCN_CNT_CODE)=0A= + section_data[otherix - 1].ms_type =3D mst_text;=0A= + else if (characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)=0A= + section_data[otherix - 1].ms_type =3D mst_data;=0A= + else if (characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)=0A= + section_data[otherix - 1].ms_type =3D mst_bss;=0A= + else=0A= + section_data[otherix - 1].ms_type =3D mst_unknown;=0A= + }=0A= }=0A= =20=0A= expdata =3D (unsigned char *) xmalloc (export_size);=0A= @@ -321,7 +491,7 @@ read_pe_exported_syms (struct objfile *o=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= @@ -331,31 +501,183 @@ 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= + printf_filtered (_("DLL \"%s\" has %ld export entries, base=3D%ld\n"),= =0A= + 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)=0A= + && (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 strchr (forward_name, '.');=0A= +=0A= + if (sep)=0A= + {=0A= + int len =3D (int) (sep - forward_name);=0A= + forward_dll_name =3D xmalloc (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= + if (sep)=0A= + xfree (forward_dll_name);=0A= + continue;=0A= + }=0A= =20=0A= - for (sectix =3D 0; sectix < PE_SECTION_TABLE_SIZE; ++sectix)=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= + static char null_char =3D '\0';=0A= +=0A= + add_pe_exported_sym (&null_char, func_rva, ordinal,=0A= + section_data, dll_name, objfile);=0A= + ++nbnormal;=0A= + }=0A= + else if (debug_coff_pe_read)=0A= + printf_filtered (_("Export name \"%s\" ord. %lu, RVA 0x%lx \=0A= +in dll \"%s\" not handled\n"),=0A= + funcname, ordinal, func_rva, dll_name);=0A= + }=0A= }=0A= =20=0A= + if (debug_coff_pe_read)=0A= + printf_filtered (_("Finished reading \"%s\", exports %ld, forwards \= =0A= +%ld, total %ld/%ld.\n"),=0A= + dll_name, nbnormal, nbforward,=0A= + nbnormal + nbforward, nexp);=0A= /* Discard expdata. */=0A= do_cleanups (back_to);=0A= }=0A= +=0A= +/* Extract for BFD 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= +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= +void _initialize_coff_pe_read (void);=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.16=0A= diff -u -p -r1.16 windows-tdep.c=0A= --- windows-tdep.c 5 Jun 2012 13:50:57 -0000 1.16=0A= +++ windows-tdep.c 6 Nov 2012 13:37:01 -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_0001_01CDBC33.D1CA4320--