support biarch gcore?

Mark Kettenis mark.kettenis@xs4all.nl
Mon Jul 5 11:55:00 GMT 2010


> Date: Mon, 5 Jul 2010 09:12:35 +0200
> From: Jan Kratochvil <jan.kratochvil@redhat.com>
> 
> On Mon, 05 Jul 2010 06:52:37 +0200, Jon Zhou wrote:
> > Regarding this case, does the current release solve it ? I just tried the
> > patch but looks it doesn't work
> 
> Issue is tracked at:
> 	amd64 gdb generates corrupted 32bit core file
> 	http://sourceware.org/bugzilla/show_bug.cgi?id=11467
> 
> There was a patchset by H.J.Lu but it did not make it in FSF GDB:
> 	PATCH: PR corefiles/11467: amd64 gdb generates corrupted 32bit core file
> 	http://sourceware.org/ml/gdb-patches/2010-04/msg00315.html
> with the last mail of this thread:
> 	http://sourceware.org/ml/gdb-patches/2010-04/msg00427.html
> 	> Please stop sending diffs until you understand how the code is
> 	> supposed to work.
> 
> The Fedora patch
> 	http://cvs.fedoraproject.org/viewvc/rpms/gdb/devel/gdb-6.5-gcore-i386-on-amd64.patch?content-type=text%2Fplain&view=co
> 
> will be rebased or replaced by H.J.Lu's one for gdb-7.2-pre by 2010-07-27.

The proper way to fix the issue is to add proper cross-core support to
BFD for i386 and amd64 like was done for powerpc/powerpc64 a couple of
years ago.  See the thread starting at:

http://sourceware.org/ml/binutils/2010-04/msg00225.html

Perhaps I need to resubmit that diff now that things have settled down
a bit.

With that diff in, there still is a GDB issue that needs to be
resolved.  The core generation code in
linux-nat.c:linux_nat_do_thread_registers() allocates a buffer of type
gdb_gregset_t to store the registers.  Since its size differs between
i386 and amd64 the size passed to _reget_from_core_section() is always
the size of the amd64 gdb_gregset_t.  Since the current code checks
for an exact match, it fails to return a regset, and things go
downhill from there.

Fixing the code in linux-nat.c is a bit nasty:

* The definition of the 32-bit version of gdb_gregset_t isn't readily
  available on 64-bit systems.

* The code is used on all Linux platforms and only a few of them are
  bi-arch.

An alternative solution would be to make _regset_from_core_section() a
little bit more forgiving.  The diff below works since the size of the
amd64 gdb_gregset_t is larger than the i386-version.


2010-07-05  Mark Kettenis  <kettenis@gnu.org>

        * i386-tdep.c (i386_supply_gregset, i386_collect_gregset)
        (i386_regset_from_core_section): Relax check for size of .reg
        section.

Index: i386-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.c,v
retrieving revision 1.316
diff -u -p -r1.316 i386-tdep.c
--- i386-tdep.c	22 Jun 2010 02:15:45 -0000	1.316
+++ i386-tdep.c	5 Jul 2010 11:50:55 -0000
@@ -2775,7 +2775,7 @@ i386_supply_gregset (const struct regset
   const gdb_byte *regs = gregs;
   int i;
 
-  gdb_assert (len == tdep->sizeof_gregset);
+  gdb_assert (len >= tdep->sizeof_gregset);
 
   for (i = 0; i < tdep->gregset_num_regs; i++)
     {
@@ -2799,7 +2799,7 @@ i386_collect_gregset (const struct regse
   gdb_byte *regs = gregs;
   int i;
 
-  gdb_assert (len == tdep->sizeof_gregset);
+  gdb_assert (len >= tdep->sizeof_gregset);
 
   for (i = 0; i < tdep->gregset_num_regs; i++)
     {
@@ -2880,7 +2880,7 @@ i386_regset_from_core_section (struct gd
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  if (strcmp (sect_name, ".reg") == 0 && sect_size == tdep->sizeof_gregset)
+  if (strcmp (sect_name, ".reg") == 0 && sect_size >= tdep->sizeof_gregset)
     {
       if (tdep->gregset == NULL)
 	tdep->gregset = regset_alloc (gdbarch, i386_supply_gregset,










More information about the Gdb mailing list