Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: "Pierre Muller" <pierre.muller@ics-cnrs.unistra.fr>
To: <gdb-patches@sourceware.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	[thread overview]
Message-ID: <006001cdaada$00c81f00$02585d00$@muller@ics-cnrs.unistra.fr> (raw)
In-Reply-To: <83y5jb7rfe.fsf@gnu.org>

[-- Attachment #1: Type: text/plain, Size: 2815 bytes --]

  Eli reported a problem with 
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. 
  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 
$2 = 126
(for instance, depending on when you do the call).

  Could someone please test the patch and 
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 
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 
empty entries in the RVA addresses array).
 
  I did not separate the two parts as I was unsure if 
they are really independent.


Comments most welcome,


Pierre Muller
GDB pascal language maintainer




> -----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.

[-- Attachment #2: fix-dll-offset.patch --]
[-- Type: application/octet-stream, Size: 7399 bytes --]

projecttype:gdb
revision:HEAD
email:muller@ics.u-strasbg.fr

2012-10-15  Pierre Muller  <muller@ics.u-strasbg.fr>

	* coff-pe-read.h (pe_text_section_offset): Declare new function.
	* coff-pe-read.c (pe_as16): New function.
	(read_pe_exported_syms): Use ordinal of function to
	retrieve correct RVA address of function.
	(pe_text_section_offset): New function.

	* windows-tdep.c (windows_xfer_shared_library): Use
	pe_text_section_offset function instead of possibly wrong
	0x1000 constant for .text sextion offset.


Index: src/gdb/coff-pe-read.h
===================================================================
RCS file: /cvs/src/src/gdb/coff-pe-read.h,v
retrieving revision 1.11
diff -u -p -r1.11 coff-pe-read.h
--- src/gdb/coff-pe-read.h	4 Jan 2012 08:17:00 -0000	1.11
+++ src/gdb/coff-pe-read.h	15 Oct 2012 12:36:49 -0000
@@ -21,11 +21,15 @@
 
 #if !defined (COFF_PE_READ_H)
 #define COFF_PE_READ_H
+#include "defs.h"
 
 struct objfile;
+struct bfd;
 
 /* Read the export table and convert it to minimal symbol table
    entries */
 extern void read_pe_exported_syms (struct objfile *objfile);
 
+extern CORE_ADDR pe_text_section_offset (struct bfd *abfd);
+
 #endif /* !defined (COFF_PE_READ_H) */
Index: src/gdb/coff-pe-read.c
===================================================================
RCS file: /cvs/src/src/gdb/coff-pe-read.c,v
retrieving revision 1.17
diff -u -p -r1.17 coff-pe-read.c
--- src/gdb/coff-pe-read.c	4 Jan 2012 08:17:00 -0000	1.17
+++ src/gdb/coff-pe-read.c	15 Oct 2012 12:36:49 -0000
@@ -170,6 +170,14 @@ pe_get32 (bfd *abfd, int where)
 }
 
 static unsigned int
+pe_as16 (void *ptr)
+{
+  unsigned char *b = ptr;
+
+  return b[0] + (b[1] << 8);
+}
+
+static unsigned int
 pe_as32 (void *ptr)
 {
   unsigned char *b = ptr;
@@ -336,26 +344,119 @@ read_pe_exported_syms (struct objfile *o
     {
       /* Pointer to the names vector.  */
       unsigned long name_rva = pe_as32 (erva + name_rvas + i * 4);
+      /* Retrieve ordinal value */
+
+      unsigned long ordinal = pe_as16 (erva + ordinals + i * 2);
+
 
       /* Pointer to the function address vector.  */
-      unsigned long func_rva = pe_as32 (erva + exp_funcbase + i * 4);
+      /* This is relatived to ordinal value. */
+      unsigned long func_rva = pe_as32 (erva + exp_funcbase +
+                                        ordinal * 4);
 
       /* Find this symbol's section in our own array.  */
       int sectix = 0;
+      int section_found = 0;
 
       for (sectix = 0; sectix < PE_SECTION_TABLE_SIZE; ++sectix)
 	{
 	  if ((func_rva >= section_data[sectix].rva_start)
 	      && (func_rva < section_data[sectix].rva_end))
 	    {
+	      section_found = 1;
 	      add_pe_exported_sym (erva + name_rva,
 				   func_rva,
 				   section_data + sectix, dll_name, objfile);
 	      break;
 	    }
 	}
+      if (!section_found)
+	{
+	  char * forward_name = (char *) (erva + func_rva);
+	  char * funcname = (char *) (erva + name_rva);
+          if ((func_rva >= export_rva) 
+              && (func_rva < export_rva + export_size)) 
+	  printf ("%s is a forward to %s\n", funcname, forward_name);
+	}
     }
 
   /* Discard expdata.  */
   do_cleanups (back_to);
 }
+
+CORE_ADDR
+pe_text_section_offset (struct bfd *abfd)
+
+{
+  bfd *dll = abfd;
+  unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
+  unsigned long export_rva, export_size, nsections, secptr, expptr;
+  unsigned long exp_funcbase;
+  unsigned char *expdata, *erva;
+  unsigned long name_rvas, ordinals, nexp, ordbase;
+  char *dll_name;
+  int is_pe64 = 0;
+  int is_pe32 = 0;
+
+  char const *target = bfd_get_target (dll);
+
+  is_pe64 = (strcmp (target, "pe-x86-64") == 0
+	     || strcmp (target, "pei-x86-64") == 0);
+  is_pe32 = (strcmp (target, "pe-i386") == 0
+	     || strcmp (target, "pei-i386") == 0
+	     || strcmp (target, "pe-arm-wince-little") == 0
+	     || strcmp (target, "pei-arm-wince-little") == 0);
+
+  if (!is_pe32 && !is_pe64)
+    {
+      /* This is not a recognized PE format file.  Abort now, because
+	 the code is untested on anything else.  *FIXME* test on
+	 further architectures and loosen or remove this test.  */
+      return 0;
+    }
+
+  /* Get pe_header, optional header and numbers of export entries.  */
+  pe_header_offset = pe_get32 (dll, 0x3c);
+  opthdr_ofs = pe_header_offset + 4 + 20;
+  if (is_pe64)
+    num_entries = pe_get32 (dll, opthdr_ofs + 108);
+  else
+    num_entries = pe_get32 (dll, opthdr_ofs + 92);
+
+  if (num_entries < 1)		/* No exports.  */
+    {
+      return 0;
+    }
+
+  if (is_pe64)
+    {
+      export_rva = pe_get32 (dll, opthdr_ofs + 112);
+      export_size = pe_get32 (dll, opthdr_ofs + 116);
+    }
+  else
+    {
+      export_rva = pe_get32 (dll, opthdr_ofs + 96);
+      export_size = pe_get32 (dll, opthdr_ofs + 100);
+    }
+  nsections = pe_get16 (dll, pe_header_offset + 4 + 2);
+  secptr = (pe_header_offset + 4 + 20 +
+	    pe_get16 (dll, pe_header_offset + 4 + 16));
+  expptr = 0;
+
+  /* Get the rva and size of the export section.  */
+  for (i = 0; i < nsections; i++)
+    {
+      char sname[8];
+      unsigned long secptr1 = secptr + 40 * i;
+      unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
+      unsigned long vsize = pe_get32 (dll, secptr1 + 16);
+      unsigned long fptr = pe_get32 (dll, secptr1 + 20);
+
+      bfd_seek (dll, (file_ptr) secptr1, SEEK_SET);
+      bfd_bread (sname, (bfd_size_type) 8, dll);
+      if (strcmp (sname, ".text") == 0)
+	return vaddr;
+    }
+
+  return 0;
+}
Index: src/gdb/windows-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/windows-tdep.c,v
retrieving revision 1.16
diff -u -p -r1.16 windows-tdep.c
--- src/gdb/windows-tdep.c	5 Jun 2012 13:50:57 -0000	1.16
+++ src/gdb/windows-tdep.c	15 Oct 2012 12:36:49 -0000
@@ -27,6 +27,9 @@
 #include "gdbcmd.h"
 #include "gdbthread.h"
 #include "objfiles.h"
+#include "symfile.h"
+#include "coff-pe-read.h"
+#include "gdb_bfd.h"
 
 struct cmd_list_element *info_w32_cmdlist;
 
@@ -387,6 +390,9 @@ windows_xfer_shared_library (const char*
 			     struct gdbarch *gdbarch, struct obstack *obstack)
 {
   char *p;
+  struct bfd * dll;
+  CORE_ADDR text_offset;
+  CORE_ADDR default_text_offset = 0x1000;
   obstack_grow_str (obstack, "<library name=\"");
   p = xml_escape_text (so_name);
   obstack_grow_str (obstack, p);
@@ -395,7 +401,19 @@ windows_xfer_shared_library (const char*
   /* The symbols in a dll are offset by 0x1000, which is the
      offset from 0 of the first byte in an image - because of the file
      header and the section alignment.  */
-  obstack_grow_str (obstack, paddress (gdbarch, load_addr + 0x1000));
+  dll = gdb_bfd_open_maybe_remote (so_name);
+  if (dll != NULL)
+    {
+      text_offset = pe_text_section_offset (dll);
+      if (text_offset != default_text_offset)
+        warning (_("DLL %s has .text section at offset %s\n"),so_name,
+		 core_addr_to_string (text_offset));
+      gdb_bfd_unref (dll);
+    }
+  else
+    text_offset = default_text_offset;
+
+  obstack_grow_str (obstack, paddress (gdbarch, load_addr + text_offset));
   obstack_grow_str (obstack, "\"/></library>");
 }
 

       reply	other threads:[~2012-10-15 13:36 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <83a9vs89r9.fsf@gnu.org>
     [not found] ` <201210120953.q9C9rqfu020865@glazunov.sibelius.xs4all.nl>
     [not found]   ` <834nm07z0s.fsf@gnu.org>
     [not found]     ` <5077FEB9.4030304@redhat.com>
     [not found]       ` <83y5jb7rfe.fsf@gnu.org>
2012-10-15 13:36         ` Pierre Muller [this message]
2012-10-24 19:45           ` Joel Brobecker
2012-10-25 12:21             ` Pierre Muller
2012-11-05 17:11               ` Joel Brobecker
2012-11-06 14:31                 ` [RFC-v2] " Pierre Muller
     [not found]                 ` <50991f5f.8382440a.1100.ffff82abSMTPIN_ADDED@mx.google.com>
2012-11-07 19:44                   ` Pedro Alves
2012-11-08  9:54                     ` [RFC-v3] " Pierre Muller
2012-11-22 17:30                       ` Joel Brobecker
2012-11-22 17:51                         ` Pedro Alves
2012-11-25 22:50                         ` [RFC-v4] " Pierre Muller
2012-11-26 17:22                           ` Joel Brobecker
2012-11-26 18:36                             ` Tom Tromey
2012-11-26 20:58                               ` Joel Brobecker
     [not found]                         ` <15690.5992342674$1353883881@news.gmane.org>
2012-11-26  4:04                           ` asmwarrior
2012-11-26 10:14                             ` Pierre Muller
     [not found]                             ` <50b340fb.0aec440a.1c48.5818SMTPIN_ADDED_BROKEN@mx.google.com>
2012-11-26 11:39                               ` Pedro Alves
2012-11-26 16:54                           ` Tom Tromey
2012-11-27 14:59                             ` [RFC-v5] " Pierre Muller
2012-12-07  7:10                               ` Joel Brobecker
2012-12-07 15:23                                 ` asmwarrior
2012-12-07 15:41                                   ` Pierre Muller
     [not found]                                   ` <29545.4593528577$1354894901@news.gmane.org>
2012-12-07 16:15                                     ` asmwarrior
2012-12-07 16:27                                       ` Pierre Muller
     [not found]                                       ` <50c21914.a750420a.2ec3.ffffe4ffSMTPIN_ADDED_BROKEN@mx.google.com>
2012-12-07 17:10                                         ` Pedro Alves
2012-12-07 17:49                                           ` Pedro Alves
2012-12-13 10:57                                             ` Pierre Muller
2012-12-13 11:07                                               ` Pedro Alves
2012-12-13 11:49                                                 ` Pedro Alves
     [not found]                                                 ` <00a201cdd931$b0ee13f0$12ca3bd0$@muller@ics-cnrs.unistra.fr>
2012-12-13 14:32                                                   ` Pedro Alves
2012-12-13 15:17                                                     ` Pierre Muller
2012-12-13 14:33                                                   ` Pedro Alves
2012-12-13 14:56                                                     ` Pierre Muller
2012-12-13 15:03                                                       ` Pedro Alves
2012-12-13 16:43                                                         ` Pedro Alves
2012-12-13 16:54                                                           ` Pierre Muller
2012-12-13 16:56                                                             ` Pedro Alves
2012-12-13 17:09                                                               ` Pierre Muller
2012-12-13 15:08                                                       ` Pierre Muller
2012-12-13 16:04                                                         ` Pedro Alves
     [not found]                                       ` <50c218e5.2850b40a.0281.ffffbef4SMTPIN_ADDED_BROKEN@mx.google.com>
2012-12-08 14:17                                         ` asmwarrior
2012-12-08 15:07                                           ` asmwarrior
2012-12-08 18:01                                           ` Pierre Muller
     [not found]                                           ` <50c38058.03d0d80a.31dd.4e28SMTPIN_ADDED_BROKEN@mx.google.com>
2012-12-09  2:45                                             ` asmwarrior
2012-12-09 12:45                                               ` Pierre Muller
     [not found]                                               ` <50c487f8.a813b40a.57d7.ffffdc7fSMTPIN_ADDED_BROKEN@mx.google.com>
2012-12-09 13:19                                                 ` asmwarrior
2012-12-13 10:48                                 ` Pierre Muller
     [not found]                                 ` <37373.4003318988$1355395714@news.gmane.org>
2012-12-13 16:16                                   ` Tom Tromey
2012-12-13 16:21                                     ` Pierre Muller
     [not found]                                     ` <12936.6976012991$1355415704@news.gmane.org>
2012-12-13 20:05                                       ` Tom Tromey
     [not found]                             ` <42721.1671988063$1354028360@news.gmane.org>
2012-11-28  2:44                               ` asmwarrior
2012-11-29  3:40                                 ` asmwarrior
2012-12-12  0:59                               ` asmwarrior
     [not found]                         ` <50b2a0d1.c849420a.3a3a.3538SMTPIN_ADDED_BROKEN@mx.google.com>
2012-12-07 16:38                           ` [RFC-v4] " Pedro Alves
2012-12-07 17:03                             ` Pierre Muller
2012-12-07 17:50                               ` Pedro Alves
     [not found]                     ` <000301cdbd96$f5cd9f10$e168dd30$%muller@ics-cnrs.unistra.fr>
2012-11-17 10:01                       ` [RFC-v3] " Eli Zaretskii
     [not found]         ` <006001cdaada$00c81f00$02585d00$%muller@ics-cnrs.unistra.fr>
2012-10-15 17:23           ` [RFC] " Eli Zaretskii
2012-11-03 10:36             ` Eli Zaretskii
2012-11-06 13:55               ` Pierre Muller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='006001cdaada$00c81f00$02585d00$@muller@ics-cnrs.unistra.fr' \
    --to=pierre.muller@ics-cnrs.unistra.fr \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox