Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH]: Use core regset when possible in linux-nat.c
@ 2006-04-06 22:06 David S. Miller
  2006-04-08 20:34 ` Daniel Jacobowitz
  0 siblings, 1 reply; 5+ messages in thread
From: David S. Miller @ 2006-04-06 22:06 UTC (permalink / raw)
  To: gdb-patches; +Cc: drow, mark.kettenis


As discussed in:

  http://sources.redhat.com/ml/gdb/2006-04/msg00030.html

Some Linux platforms have different ptrace vs. core file
register layouts.

The suggested way to handle this is to use the core regset
interfaces.  Not all Linux target support that yet, so we
have to check and use the old code if the target does not
have core regset support.

Tested on sparc*-*-linux* Both gdb.base/corefile.exp and
gdb.base/gcore.exp pass (*1), which is what I was originally trying to
achieve :-)

Ok to apply?

*1: The test in corefile.exp to look at the mmap() area pointed
    to by buf2 fails due to a Linux kernel bug, it doesn't dump
    mmap() areas which have not been written to into the core
    file so gdb can't look at it.  I've posted a patch to linux-kernel
    already suggesting to take away that check in the ELF core dumper.

2006-04-06  David S. Miller  <davem@sunset.davemloft.net>

	* linux-nat.c (linux_nat_do_thread_registers): Use the
	regset_from_core_section infrastructure if the target
	supports it.
	* Makefile.in: Update dependencies.
	
--- ./linux-nat.c.~1~	2006-04-05 18:08:11.000000000 -0700
+++ ./linux-nat.c	2006-04-06 14:56:06.000000000 -0700
@@ -36,6 +36,7 @@
 #include "gdbthread.h"
 #include "gdbcmd.h"
 #include "regcache.h"
+#include "regset.h"
 #include "inf-ptrace.h"
 #include "auxv.h"
 #include <sys/param.h>		/* for MAXPATHLEN */
@@ -2529,21 +2530,49 @@ linux_nat_do_thread_registers (bfd *obfd
   gdb_fpxregset_t fpxregs;
 #endif
   unsigned long lwp = ptid_get_lwp (ptid);
-
-  fill_gregset (&gregs, -1);
+  struct gdbarch *gdbarch = current_gdbarch;
+  const struct regset *regset;
+  int core_regset_p;
+
+  core_regset_p = gdbarch_regset_from_core_section_p (gdbarch);
+  if (core_regset_p)
+    {
+      regset = gdbarch_regset_from_core_section (gdbarch, ".reg",
+						 sizeof (gregs));
+      regset->collect_regset (regset, current_regcache, -1,
+			      &gregs, sizeof (gregs));
+    }
+  else
+    fill_gregset (&gregs, -1);
   note_data = (char *) elfcore_write_prstatus (obfd,
 					       note_data,
 					       note_size,
 					       lwp,
 					       stop_signal, &gregs);
 
-  fill_fpregset (&fpregs, -1);
+  if (core_regset_p)
+    {
+      regset = gdbarch_regset_from_core_section (gdbarch, ".reg2",
+						 sizeof (fpregs));
+      regset->collect_regset (regset, current_regcache, -1,
+			      &fpregs, sizeof (fpregs));
+    }
+  else
+    fill_fpregset (&fpregs, -1);
   note_data = (char *) elfcore_write_prfpreg (obfd,
 					      note_data,
 					      note_size,
 					      &fpregs, sizeof (fpregs));
 #ifdef FILL_FPXREGSET
-  fill_fpxregset (&fpxregs, -1);
+  if (core_regset_p)
+    {
+      regset = gdbarch_regset_from_core_section (gdbarch, ".reg-xfp",
+						 sizeof (fpxregs));
+      regset->collect_regset (regset, current_regcache, -1,
+			      &fpxregs, sizeof (fpxregs));
+    }
+  else
+    fill_fpxregset (&fpxregs, -1);
   note_data = (char *) elfcore_write_prxfpreg (obfd,
 					       note_data,
 					       note_size,
--- ./Makefile.in.~1~	2006-04-05 15:55:07.000000000 -0700
+++ ./Makefile.in	2006-04-06 14:56:33.000000000 -0700
@@ -2195,8 +2195,8 @@ linux-fork.o: linux-fork.c $(defs_h) $(i
 	$(linux_nat_h)
 linux-nat.o: linux-nat.c $(defs_h) $(inferior_h) $(target_h) $(gdb_string_h) \
 	$(gdb_wait_h) $(gdb_assert_h) $(linux_nat_h) $(gdbthread_h) \
-	$(gdbcmd_h) $(regcache_h) $(inf_ptrace_h) $(auxv_h) $(elf_bfd_h) \
-	$(gregset_h) $(gdbcore_h) $(gdbthread_h) $(gdb_stat_h) \
+	$(gdbcmd_h) $(regcache_h) $(regset_h) $(inf_ptrace_h) $(auxv_h) \
+	$(elf_bfd_h) $(gregset_h) $(gdbcore_h) $(gdbthread_h) $(gdb_stat_h) \
 	$(linux_fork_h)
 linux-thread-db.o: linux-thread-db.c $(defs_h) $(gdb_assert_h) \
 	$(gdb_proc_service_h) $(gdb_thread_db_h) $(bfd_h) $(exceptions_h) \


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH]: Use core regset when possible in linux-nat.c
  2006-04-06 22:06 [PATCH]: Use core regset when possible in linux-nat.c David S. Miller
@ 2006-04-08 20:34 ` Daniel Jacobowitz
  2006-04-08 21:54   ` David S. Miller
  0 siblings, 1 reply; 5+ messages in thread
From: Daniel Jacobowitz @ 2006-04-08 20:34 UTC (permalink / raw)
  To: David S. Miller; +Cc: gdb-patches, mark.kettenis

On Thu, Apr 06, 2006 at 03:03:30PM -0700, David S. Miller wrote:
> *1: The test in corefile.exp to look at the mmap() area pointed
>     to by buf2 fails due to a Linux kernel bug, it doesn't dump
>     mmap() areas which have not been written to into the core
>     file so gdb can't look at it.  I've posted a patch to linux-kernel
>     already suggesting to take away that check in the ELF core dumper.

Or, we could just change the test.  I don't know...

> 2006-04-06  David S. Miller  <davem@sunset.davemloft.net>
> 
> 	* linux-nat.c (linux_nat_do_thread_registers): Use the
> 	regset_from_core_section infrastructure if the target
> 	supports it.
> 	* Makefile.in: Update dependencies.

Almost.  I know I suggested changing the fallback case from your
original suggestion, but this isn't quite what I meant:

> -  fill_fpregset (&fpregs, -1);
> +  if (core_regset_p)
> +    {
> +      regset = gdbarch_regset_from_core_section (gdbarch, ".reg2",
> +						 sizeof (fpregs));
> +      regset->collect_regset (regset, current_regcache, -1,
> +			      &fpregs, sizeof (fpregs));
> +    }
> +  else
> +    fill_fpregset (&fpregs, -1);
>    note_data = (char *) elfcore_write_prfpreg (obfd,
>  					      note_data,
>  					      note_size,
>  					      &fpregs, sizeof (fpregs));

A target which only defines .reg and not .reg2 will crash here.
We'd still have to check for non-NULL; I just think that if the
target supports regset_from_core_section, and still returns NULL,
that that's a pretty good hint we have nothing to write.

The other thing that bugs me about this interface may be harder to fix
- we're still assuming the two are the same, more or less, because the
regset type is required here and we use its sizeof.  A problem for
another day?


-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH]: Use core regset when possible in linux-nat.c
  2006-04-08 20:34 ` Daniel Jacobowitz
@ 2006-04-08 21:54   ` David S. Miller
  2006-05-05 20:15     ` Daniel Jacobowitz
  0 siblings, 1 reply; 5+ messages in thread
From: David S. Miller @ 2006-04-08 21:54 UTC (permalink / raw)
  To: drow; +Cc: gdb-patches, mark.kettenis

From: Daniel Jacobowitz <drow@false.org>
Date: Sat, 8 Apr 2006 16:34:37 -0400

> On Thu, Apr 06, 2006 at 03:03:30PM -0700, David S. Miller wrote:
> > *1: The test in corefile.exp to look at the mmap() area pointed
> >     to by buf2 fails due to a Linux kernel bug, it doesn't dump
> >     mmap() areas which have not been written to into the core
> >     file so gdb can't look at it.  I've posted a patch to linux-kernel
> >     already suggesting to take away that check in the ELF core dumper.
> 
> Or, we could just change the test.  I don't know...

I think something like that should work properly.  For example,
say you're debugging a compiler or config file parser that mmap()'s
the file being parsed.  If you get a crash and that file being looked
at is critical for debugging the problem, it should be obtainable
during the debugging session.

Perhaps the alignment of the object being parsed in that mmap()'d area
is critical for reproducing the bug.

I've been burned enough times in situations like this, where some
omitted piece of debugging information held the clue to the problem,
that I strongly hesitate to ever suggest we report less rather than
more information in a core file :-)

> > -  fill_fpregset (&fpregs, -1);
> > +  if (core_regset_p)
> > +    {
> > +      regset = gdbarch_regset_from_core_section (gdbarch, ".reg2",
> > +						 sizeof (fpregs));
> > +      regset->collect_regset (regset, current_regcache, -1,
> > +			      &fpregs, sizeof (fpregs));
> > +    }
> > +  else
> > +    fill_fpregset (&fpregs, -1);
> >    note_data = (char *) elfcore_write_prfpreg (obfd,
> >  					      note_data,
> >  					      note_size,
> >  					      &fpregs, sizeof (fpregs));
> 
> A target which only defines .reg and not .reg2 will crash here.
> We'd still have to check for non-NULL; I just think that if the
> target supports regset_from_core_section, and still returns NULL,
> that that's a pretty good hint we have nothing to write.

Ok, I've attached an updated version of the patch below.

> The other thing that bugs me about this interface may be harder to fix
> - we're still assuming the two are the same, more or less, because the
> regset type is required here and we use its sizeof.  A problem for
> another day?

Perhaps.  There are some other dragons lurking here.

The targets that support regset_from_core_section fall roughly into two
categories:

1) They check that the size == the regset size.
2) They check that the size >= the regset size.

Since we define GDB_GREGSET_T to the elf regset in config/nm-linux.h it
should work out properly when host==target, but for the case of a 64-bit
host debugging it's 32-bit bretheren we're going to do some queer things.

The BFD elf layer provides quite nice support for 32-bit and 64-bit
ELF core section handling via functions like elfcore_grok_prstatus().
If it sees that the size is the 32-bit variant it will interpret the
size of the registers correctly.  Similarly for elfcore_grok_psinfo()
and elfcore_grok_pstatus().

But going the other way, we have only elfcore_write_prpsinfo() which only
can write out the native prpsinfo_t layout.  So if you have a 64-bit
Linux/Sparc gdb debugging a 32-bit process, it will write out 64-bit
core file sections for the 32-bit process :-)  Now, this works if you
try to read back in the core using the 64-bit GDB but a 32-bit GDB would
not be able to grok it.

It is something to handle properly in the future and platforms like
MIPS and PowerPC, where mixing 32-bit/64-bit environments is common,
would certainly appreciate this working fully as well.

But overall I think this updated version of the patch below is safe and
makes things no worse than they are now, and as a bonus GDB can natively
generate core files and intepret them identically to the kernel produced
core files on Linux/Sparc.

Ok to apply now?

Thanks again for all of your reviewing efforts Daniel.

2006-04-08  David S. Miller  <davem@sunset.davemloft.net>

	* linux-nat.c (linux_nat_do_thread_registers): Use the
	regset_from_core_section infrastructure if the target
	supports it.
	* Makefile.in: Update dependencies.
	
--- linux-nat.c.~1~	2006-04-08 14:18:18.000000000 -0700
+++ linux-nat.c	2006-04-08 14:21:56.000000000 -0700
@@ -36,6 +36,7 @@
 #include "gdbthread.h"
 #include "gdbcmd.h"
 #include "regcache.h"
+#include "regset.h"
 #include "inf-ptrace.h"
 #include "auxv.h"
 #include <sys/param.h>		/* for MAXPATHLEN */
@@ -2535,25 +2536,72 @@ linux_nat_do_thread_registers (bfd *obfd
   gdb_fpxregset_t fpxregs;
 #endif
   unsigned long lwp = ptid_get_lwp (ptid);
+  struct gdbarch *gdbarch = current_gdbarch;
+  const struct regset *regset;
+  int core_regset_p, record_reg_p;
+
+  core_regset_p = gdbarch_regset_from_core_section_p (gdbarch);
+  record_reg_p = 1;
+  if (core_regset_p)
+    {
+      regset = gdbarch_regset_from_core_section (gdbarch, ".reg",
+						 sizeof (gregs));
+      if (regset)
+	regset->collect_regset (regset, current_regcache, -1,
+				&gregs, sizeof (gregs));
+      else
+	record_reg_p = 0;
+    }
+  else
+    fill_gregset (&gregs, -1);
+
+  if (record_reg_p)
+    note_data = (char *) elfcore_write_prstatus (obfd,
+						 note_data,
+						 note_size,
+						 lwp,
+						 stop_signal, &gregs);
+
+  record_reg_p = 1;
+  if (core_regset_p)
+    {
+      regset = gdbarch_regset_from_core_section (gdbarch, ".reg2",
+						 sizeof (fpregs));
+      if (regset)
+	regset->collect_regset (regset, current_regcache, -1,
+				&fpregs, sizeof (fpregs));
+      else
+	record_reg_p = 0;
+    }
+  else
+    fill_fpregset (&fpregs, -1);
+
+  if (record_reg_p)
+    note_data = (char *) elfcore_write_prfpreg (obfd,
+						note_data,
+						note_size,
+						&fpregs, sizeof (fpregs));
 
-  fill_gregset (&gregs, -1);
-  note_data = (char *) elfcore_write_prstatus (obfd,
-					       note_data,
-					       note_size,
-					       lwp,
-					       stop_signal, &gregs);
-
-  fill_fpregset (&fpregs, -1);
-  note_data = (char *) elfcore_write_prfpreg (obfd,
-					      note_data,
-					      note_size,
-					      &fpregs, sizeof (fpregs));
 #ifdef FILL_FPXREGSET
-  fill_fpxregset (&fpxregs, -1);
-  note_data = (char *) elfcore_write_prxfpreg (obfd,
-					       note_data,
-					       note_size,
-					       &fpxregs, sizeof (fpxregs));
+  record_reg_p = 1;
+  if (core_regset_p)
+    {
+      regset = gdbarch_regset_from_core_section (gdbarch, ".reg-xfp",
+						 sizeof (fpxregs));
+      if (regset)
+	regset->collect_regset (regset, current_regcache, -1,
+				&fpxregs, sizeof (fpxregs));
+      else
+	record_reg_p = 0;
+    }
+  else
+    fill_fpxregset (&fpxregs, -1);
+
+  if (record_reg_p)
+    note_data = (char *) elfcore_write_prxfpreg (obfd,
+						 note_data,
+						 note_size,
+						 &fpxregs, sizeof (fpxregs));
 #endif
   return note_data;
 }
--- Makefile.in.~1~	2006-04-08 14:18:18.000000000 -0700
+++ Makefile.in	2006-04-08 14:18:22.000000000 -0700
@@ -2195,8 +2195,8 @@ linux-fork.o: linux-fork.c $(defs_h) $(i
 	$(linux_nat_h)
 linux-nat.o: linux-nat.c $(defs_h) $(inferior_h) $(target_h) $(gdb_string_h) \
 	$(gdb_wait_h) $(gdb_assert_h) $(linux_nat_h) $(gdbthread_h) \
-	$(gdbcmd_h) $(regcache_h) $(inf_ptrace_h) $(auxv_h) $(elf_bfd_h) \
-	$(gregset_h) $(gdbcore_h) $(gdbthread_h) $(gdb_stat_h) \
+	$(gdbcmd_h) $(regcache_h) $(regset_h) $(inf_ptrace_h) $(auxv_h) \
+	$(elf_bfd_h) $(gregset_h) $(gdbcore_h) $(gdbthread_h) $(gdb_stat_h) \
 	$(linux_fork_h)
 linux-thread-db.o: linux-thread-db.c $(defs_h) $(gdb_assert_h) \
 	$(gdb_proc_service_h) $(gdb_thread_db_h) $(bfd_h) $(exceptions_h) \


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH]: Use core regset when possible in linux-nat.c
  2006-04-08 21:54   ` David S. Miller
@ 2006-05-05 20:15     ` Daniel Jacobowitz
  2006-05-05 22:40       ` David S. Miller
  0 siblings, 1 reply; 5+ messages in thread
From: Daniel Jacobowitz @ 2006-05-05 20:15 UTC (permalink / raw)
  To: David S. Miller; +Cc: gdb-patches, mark.kettenis

On Sat, Apr 08, 2006 at 02:54:33PM -0700, David S. Miller wrote:
> 2006-04-08  David S. Miller  <davem@sunset.davemloft.net>
> 
> 	* linux-nat.c (linux_nat_do_thread_registers): Use the
> 	regset_from_core_section infrastructure if the target
> 	supports it.
> 	* Makefile.in: Update dependencies.

This looks perfect.  Thanks for revising it; this patch is OK.


-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH]: Use core regset when possible in linux-nat.c
  2006-05-05 20:15     ` Daniel Jacobowitz
@ 2006-05-05 22:40       ` David S. Miller
  0 siblings, 0 replies; 5+ messages in thread
From: David S. Miller @ 2006-05-05 22:40 UTC (permalink / raw)
  To: drow; +Cc: gdb-patches, mark.kettenis

From: Daniel Jacobowitz <drow@false.org>
Date: Fri, 5 May 2006 16:14:26 -0400

> On Sat, Apr 08, 2006 at 02:54:33PM -0700, David S. Miller wrote:
> > 2006-04-08  David S. Miller  <davem@sunset.davemloft.net>
> > 
> > 	* linux-nat.c (linux_nat_do_thread_registers): Use the
> > 	regset_from_core_section infrastructure if the target
> > 	supports it.
> > 	* Makefile.in: Update dependencies.
> 
> This looks perfect.  Thanks for revising it; this patch is OK.

Committed, thanks for reviewing.


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2006-05-05 22:40 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-04-06 22:06 [PATCH]: Use core regset when possible in linux-nat.c David S. Miller
2006-04-08 20:34 ` Daniel Jacobowitz
2006-04-08 21:54   ` David S. Miller
2006-05-05 20:15     ` Daniel Jacobowitz
2006-05-05 22:40       ` David S. Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox