public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* PATCH: PR corefiles/11511: gcore doesn't work with orig_rax on  Linux/amd64
@ 2010-04-17 16:11 H.J. Lu
  2010-04-17 16:25 ` Mark Kettenis
  0 siblings, 1 reply; 8+ messages in thread
From: H.J. Lu @ 2010-04-17 16:11 UTC (permalink / raw)
  To: GDB

This patch adds orig_rax support to amd64_linux_gregset_reg_offset.
amd64 has both tdep->gregset_reg_offset/tdep->gregset_num_regs and
amd64_native_gregset64_reg_offset/amd64_native_gregset64_num_regs.  They 
are identical. There is no need to keep both.  This patch also removes
amd64_native_gregset64_reg_offset/amd64_native_gregset64_num_regs. OK
to install?

Thanks.


H.J.
---
gdb/

2010-04-17  H.J. Lu  <hongjiu.lu@intel.com>

	PR corefiles/11511
	* amd64-darwin-tdep.c (amd64_darwin_thread_state_reg_offset): Make
	it static.
	(amd64_darwin_thread_state_num_regs): Removed.
	(x86_darwin_init_abi_64): Updated.

	* amd64-darwin-tdep.h (amd64_darwin_thread_state_reg_offset):
	Removed.
	(amd64_darwin_thread_state_num_regs): Likewise.

	* amd64-linux-nat.c (amd64_linux_gregset64_reg_offset): Removed.
	(_initialize_amd64_linux_nat): Don't set
	amd64_native_gregset64_reg_offset nor
	amd64_native_gregset64_num_regs.

	* amd64-linux-tdep.c (amd64_linux_gregset_reg_offset): Support
	orig_rax.

	* amd64-nat.c (amd64_native_gregset64_reg_offset): Removed.
	(amd64_native_gregset64_num_regs): Likewise.
	(amd64_native_gregset_reg_offset): Replace
	amd64_native_gregset64_reg_offset and
	amd64_native_gregset64_num_regs with tdep->gregset_reg_offset
	and tdep->gregset_num_regs.
	(amd64_supply_native_gregset): Replace
	amd64_native_gregset64_num_regs with tdep->gregset_num_regs.
	(amd64_collect_native_gregset): Likewise.

	* amd64-nat.h (amd64_native_gregset64_reg_offset): Removed.
	(amd64_native_gregset64_num_regs): Likewise.
	* amd64-tdep.h (amd64nbsd_r_reg_offset): Likewise.
	(amd64obsd_r_reg_offset): Likewise.

	* amd64fbsd-nat.c (_initialize_amd64fbsd_nat): Don't set
	amd64_native_gregset64_reg_offset.
	* amd64nbsd-nat.c (_initialize_amd64nbsd_nat): Likewise.
	* amd64obsd-nat.c (_initialize_amd64obsd_nat): Likewise.

	* amd64nbsd-tdep.c (amd64nbsd_r_reg_offset): Make it static.
	* amd64obsd-tdep.c (amd64obsd_r_reg_offset): Likewise.

	* i386-darwin-nat.c (darwin_complete_target): Don't set
	amd64_native_gregset64_reg_offset nor
	amd64_native_gregset64_num_regs.

	* i386-sol2-nat.c (amd64_sol2_gregset64_reg_offset): Removed.
	(_initialize_amd64_sol2_nat): Don't set
	amd64_native_gregset64_reg_offset nor
	amd64_native_gregset64_num_regs.

gdb/testsuite/

2010-04-17  H.J. Lu  <hongjiu.lu@intel.com>

	PR corefiles/11511
	* gdb.arch/system-gcore.exp: New.
	* gdb.arch/gcore.c: Likewise.

diff --git a/gdb/amd64-darwin-tdep.c b/gdb/amd64-darwin-tdep.c
index 20d7fae..51f83d9 100644
--- a/gdb/amd64-darwin-tdep.c
+++ b/gdb/amd64-darwin-tdep.c
@@ -45,7 +45,7 @@
 
 /* Offsets into the struct x86_thread_state64 where we'll find the saved regs.
    From <mach/i386/thread_status.h> and amd64-tdep.h.  */
-int amd64_darwin_thread_state_reg_offset[] =
+static int amd64_darwin_thread_state_reg_offset[] =
 {
   0 * 8,			/* %rax */
   1 * 8,			/* %rbx */
@@ -73,9 +73,6 @@ int amd64_darwin_thread_state_reg_offset[] =
   20 * 8			/* %gs */
 };
 
-const int amd64_darwin_thread_state_num_regs = 
-  ARRAY_SIZE (amd64_darwin_thread_state_reg_offset);
-
 /* Assuming THIS_FRAME is a Darwin sigtramp routine, return the
    address of the associated sigcontext structure.  */
 
@@ -114,7 +111,7 @@ x86_darwin_init_abi_64 (struct gdbarch_info info, struct gdbarch *gdbarch)
   tdep->sigtramp_p = i386_sigtramp_p;
   tdep->sigcontext_addr = amd64_darwin_sigcontext_addr;
   tdep->sc_reg_offset = amd64_darwin_thread_state_reg_offset;
-  tdep->sc_num_regs = amd64_darwin_thread_state_num_regs;
+  tdep->sc_num_regs = ARRAY_SIZE (amd64_darwin_thread_state_reg_offset);
 
   tdep->jb_pc_offset = 148;
 
diff --git a/gdb/amd64-darwin-tdep.h b/gdb/amd64-darwin-tdep.h
index 0b7becc..e85c312 100644
--- a/gdb/amd64-darwin-tdep.h
+++ b/gdb/amd64-darwin-tdep.h
@@ -19,10 +19,4 @@
 #ifndef __AMD64_DARWIN_TDEP_H__
 #define __AMD64_DARWIN_TDEP_H__
 
-/* Mapping between the general-purpose registers in Darwin x86-64 thread
-   state and GDB's register cache layout.
-   Indexed by amd64_regnum.  */
-extern int amd64_darwin_thread_state_reg_offset[];
-extern const int amd64_darwin_thread_state_num_regs;
-
 #endif /* __AMD64_DARWIN_TDEP_H__ */
diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
index 9812610..e35afbd 100644
--- a/gdb/amd64-linux-nat.c
+++ b/gdb/amd64-linux-nat.c
@@ -67,31 +67,6 @@
 /* Does the current host support PTRACE_GETREGSET?  */
 static int have_ptrace_getregset = -1;
 
-/* Mapping between the general-purpose registers in GNU/Linux x86-64
-   `struct user' format and GDB's register cache layout.  */
-
-static int amd64_linux_gregset64_reg_offset[] =
-{
-  RAX * 8, RBX * 8,		/* %rax, %rbx */
-  RCX * 8, RDX * 8,		/* %rcx, %rdx */
-  RSI * 8, RDI * 8,		/* %rsi, %rdi */
-  RBP * 8, RSP * 8,		/* %rbp, %rsp */
-  R8 * 8, R9 * 8,		/* %r8 ... */
-  R10 * 8, R11 * 8,
-  R12 * 8, R13 * 8,
-  R14 * 8, R15 * 8,		/* ... %r15 */
-  RIP * 8, EFLAGS * 8,		/* %rip, %eflags */
-  CS * 8, SS * 8,		/* %cs, %ss */
-  DS * 8, ES * 8,		/* %ds, %es */
-  FS * 8, GS * 8,		/* %fs, %gs */
-  -1, -1, -1, -1, -1, -1, -1, -1,
-  -1, -1, -1, -1, -1, -1, -1, -1,
-  -1, -1, -1, -1, -1, -1, -1, -1,
-  -1, -1, -1, -1, -1, -1, -1, -1, -1,
-  -1, -1, -1, -1, -1, -1, -1, -1,
-  -1, -1, -1, -1, -1, -1, -1, -1,
-  ORIG_RAX * 8
-};
 \f
 
 /* Mapping between the general-purpose registers in GNU/Linux x86-64
@@ -807,13 +782,9 @@ _initialize_amd64_linux_nat (void)
 
   amd64_native_gregset32_reg_offset = amd64_linux_gregset32_reg_offset;
   amd64_native_gregset32_num_regs = I386_LINUX_NUM_REGS;
-  amd64_native_gregset64_reg_offset = amd64_linux_gregset64_reg_offset;
-  amd64_native_gregset64_num_regs = AMD64_LINUX_NUM_REGS;
 
   gdb_assert (ARRAY_SIZE (amd64_linux_gregset32_reg_offset)
 	      == amd64_native_gregset32_num_regs);
-  gdb_assert (ARRAY_SIZE (amd64_linux_gregset64_reg_offset)
-	      == amd64_native_gregset64_num_regs);
 
   /* Fill in the generic GNU/Linux methods.  */
   t = linux_target ();
diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
index 1205e31..f249d5d 100644
--- a/gdb/amd64-linux-tdep.c
+++ b/gdb/amd64-linux-tdep.c
@@ -87,7 +87,14 @@ static int amd64_linux_gregset_reg_offset[] =
   23 * 8,			/* %ds */
   24 * 8,			/* %es */
   25 * 8,			/* %fs */
-  26 * 8			/* %gs */
+  26 * 8,			/* %gs */
+  -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1,
+  15 * 8			/* "orig_rax" */
 };
 \f
 
diff --git a/gdb/amd64-nat.c b/gdb/amd64-nat.c
index bcf303e..6ce2e25 100644
--- a/gdb/amd64-nat.c
+++ b/gdb/amd64-nat.c
@@ -45,18 +45,14 @@
 int *amd64_native_gregset32_reg_offset;
 int amd64_native_gregset32_num_regs = I386_NUM_GREGS;
 
-/* General-purpose register mapping for native 64-bit code.  */
-int *amd64_native_gregset64_reg_offset;
-int amd64_native_gregset64_num_regs = AMD64_NUM_GREGS;
-
 /* Return the offset of REGNUM within the appropriate native
    general-purpose register set.  */
 
 static int
 amd64_native_gregset_reg_offset (struct gdbarch *gdbarch, int regnum)
 {
-  int *reg_offset = amd64_native_gregset64_reg_offset;
-  int num_regs = amd64_native_gregset64_num_regs;
+  int *reg_offset;
+  int num_regs;
 
   gdb_assert (regnum >= 0);
 
@@ -65,6 +61,12 @@ amd64_native_gregset_reg_offset (struct gdbarch *gdbarch, int regnum)
       reg_offset = amd64_native_gregset32_reg_offset;
       num_regs = amd64_native_gregset32_num_regs;
     }
+  else
+    {
+      struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+      reg_offset = tdep->gregset_reg_offset;
+      num_regs = tdep->gregset_num_regs;
+    }
 
   if (num_regs > gdbarch_num_regs (gdbarch))
     num_regs = gdbarch_num_regs (gdbarch);
@@ -94,11 +96,16 @@ amd64_supply_native_gregset (struct regcache *regcache,
 {
   const char *regs = gregs;
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
-  int num_regs = amd64_native_gregset64_num_regs;
+  int num_regs;
   int i;
 
   if (gdbarch_ptr_bit (gdbarch) == 32)
     num_regs = amd64_native_gregset32_num_regs;
+  else
+    {
+      struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+      num_regs = tdep->gregset_num_regs;
+    }
 
   if (num_regs > gdbarch_num_regs (gdbarch))
     num_regs = gdbarch_num_regs (gdbarch);
@@ -125,7 +132,7 @@ amd64_collect_native_gregset (const struct regcache *regcache,
 {
   char *regs = gregs;
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
-  int num_regs = amd64_native_gregset64_num_regs;
+  int num_regs;
   int i;
 
   if (gdbarch_ptr_bit (gdbarch) == 32)
@@ -146,6 +153,11 @@ amd64_collect_native_gregset (const struct regcache *regcache,
 	    memset (regs + amd64_native_gregset_reg_offset (gdbarch, i), 0, 8);
 	}
     }
+  else
+    {
+      struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+      num_regs = tdep->gregset_num_regs;
+    }
 
   if (num_regs > gdbarch_num_regs (gdbarch))
     num_regs = gdbarch_num_regs (gdbarch);
diff --git a/gdb/amd64-nat.h b/gdb/amd64-nat.h
index d1f9199..50b26aa 100644
--- a/gdb/amd64-nat.h
+++ b/gdb/amd64-nat.h
@@ -27,10 +27,6 @@ struct regcache;
 extern int *amd64_native_gregset32_reg_offset;
 extern int amd64_native_gregset32_num_regs;
 
-/* General-purpose register set description for native 64-bit code.  */
-extern int *amd64_native_gregset64_reg_offset;
-extern int amd64_native_gregset64_num_regs;
-
 /* Return whether the native general-purpose register set supplies
    register REGNUM.  */
 
diff --git a/gdb/amd64-tdep.h b/gdb/amd64-tdep.h
index 9f07dda..6830909 100644
--- a/gdb/amd64-tdep.h
+++ b/gdb/amd64-tdep.h
@@ -109,12 +109,6 @@ void amd64_classify (struct type *type, enum amd64_reg_class class[2]);
 
 \f
 
-/* Variables exported from amd64nbsd-tdep.c.  */
-extern int amd64nbsd_r_reg_offset[];
-
-/* Variables exported from amd64obsd-tdep.c.  */
-extern int amd64obsd_r_reg_offset[];
-
 /* Variables exported from amd64fbsd-tdep.c.  */
 extern CORE_ADDR amd64fbsd_sigtramp_start_addr;
 extern CORE_ADDR amd64fbsd_sigtramp_end_addr;
diff --git a/gdb/amd64fbsd-nat.c b/gdb/amd64fbsd-nat.c
index 2ad6402..f079519 100644
--- a/gdb/amd64fbsd-nat.c
+++ b/gdb/amd64fbsd-nat.c
@@ -151,7 +151,6 @@ _initialize_amd64fbsd_nat (void)
   int offset;
 
   amd64_native_gregset32_reg_offset = amd64fbsd32_r_reg_offset;
-  amd64_native_gregset64_reg_offset = amd64fbsd64_r_reg_offset;
 
   /* Add some extra features to the common *BSD/i386 target.  */
   t = amd64bsd_target ();
diff --git a/gdb/amd64nbsd-nat.c b/gdb/amd64nbsd-nat.c
index 0e15163..8925f9b 100644
--- a/gdb/amd64nbsd-nat.c
+++ b/gdb/amd64nbsd-nat.c
@@ -67,7 +67,6 @@ _initialize_amd64nbsd_nat (void)
 
   amd64_native_gregset32_reg_offset = amd64nbsd32_r_reg_offset;
   amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64nbsd32_r_reg_offset);
-  amd64_native_gregset64_reg_offset = amd64nbsd_r_reg_offset;
 
   /* Add some extra features to the common *BSD/amd64 target.  */
   t = amd64bsd_target ();
diff --git a/gdb/amd64nbsd-tdep.c b/gdb/amd64nbsd-tdep.c
index fb09e55..0a5c760 100644
--- a/gdb/amd64nbsd-tdep.c
+++ b/gdb/amd64nbsd-tdep.c
@@ -68,7 +68,7 @@ amd64nbsd_mcontext_addr (struct frame_info *this_frame)
    format and GDB's register cache layout.  */
 
 /* From <machine/reg.h>.  */
-int amd64nbsd_r_reg_offset[] =
+static int amd64nbsd_r_reg_offset[] =
 {
   14 * 8,			/* %rax */
   13 * 8,			/* %rbx */
diff --git a/gdb/amd64obsd-nat.c b/gdb/amd64obsd-nat.c
index 3987b99..c9a8f22 100644
--- a/gdb/amd64obsd-nat.c
+++ b/gdb/amd64obsd-nat.c
@@ -136,7 +136,6 @@ _initialize_amd64obsd_nat (void)
 {
   amd64_native_gregset32_reg_offset = amd64obsd32_r_reg_offset;
   amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64obsd32_r_reg_offset);
-  amd64_native_gregset64_reg_offset = amd64obsd_r_reg_offset;
 
   /* We've got nothing to add to the common *BSD/amd64 target.  */
   add_target (amd64bsd_target ());
diff --git a/gdb/amd64obsd-tdep.c b/gdb/amd64obsd-tdep.c
index 89eac13..d66e8ea 100644
--- a/gdb/amd64obsd-tdep.c
+++ b/gdb/amd64obsd-tdep.c
@@ -157,7 +157,7 @@ amd64obsd_sigcontext_addr (struct frame_info *this_frame)
    format and GDB's register cache layout.  */
 
 /* From <machine/reg.h>.  */
-int amd64obsd_r_reg_offset[] =
+static int amd64obsd_r_reg_offset[] =
 {
   14 * 8,			/* %rax */
   13 * 8,			/* %rbx */
diff --git a/gdb/i386-darwin-nat.c b/gdb/i386-darwin-nat.c
index 2584dbc..e03ad1c 100644
--- a/gdb/i386-darwin-nat.c
+++ b/gdb/i386-darwin-nat.c
@@ -573,8 +573,6 @@ void
 darwin_complete_target (struct target_ops *target)
 {
 #ifdef BFD64
-  amd64_native_gregset64_reg_offset = amd64_darwin_thread_state_reg_offset;
-  amd64_native_gregset64_num_regs = amd64_darwin_thread_state_num_regs;
   amd64_native_gregset32_reg_offset = i386_darwin_thread_state_reg_offset;
   amd64_native_gregset32_num_regs = i386_darwin_thread_state_num_regs;
 #endif
diff --git a/gdb/i386-sol2-nat.c b/gdb/i386-sol2-nat.c
index b680e66..06b9189 100644
--- a/gdb/i386-sol2-nat.c
+++ b/gdb/i386-sol2-nat.c
@@ -46,37 +46,6 @@
 #include "amd64-nat.h"
 #include "amd64-tdep.h"
 
-/* Mapping between the general-purpose registers in gregset_t format
-   and GDB's register cache layout.  */
-
-/* From <sys/regset.h>.  */
-static int amd64_sol2_gregset64_reg_offset[] = {
-  14 * 8,			/* %rax */
-  11 * 8,			/* %rbx */
-  13 * 8,			/* %rcx */
-  12 * 8,			/* %rdx */
-  9 * 8,			/* %rsi */
-  8 * 8,			/* %rdi */
-  10 * 8,			/* %rbp */
-  20 * 8,			/* %rsp */
-  7 * 8,			/* %r8 ... */
-  6 * 8,
-  5 * 8,
-  4 * 8,
-  3 * 8,
-  2 * 8,
-  1 * 8,
-  0 * 8,			/* ... %r15 */
-  17 * 8,			/* %rip */
-  16 * 8,			/* %eflags */
-  18 * 8,			/* %cs */
-  21 * 8,			/* %ss */
-  25 * 8,			/* %ds */
-  24 * 8,			/* %es */
-  22 * 8,			/* %fs */
-  23 * 8			/* %gs */
-};
-
 /* 32-bit registers are provided by Solaris in 64-bit format, so just
    give a subset of the list above.  */
 static int amd64_sol2_gregset32_reg_offset[] = {
@@ -149,9 +118,6 @@ _initialize_amd64_sol2_nat (void)
   amd64_native_gregset32_reg_offset = amd64_sol2_gregset32_reg_offset;
   amd64_native_gregset32_num_regs =
     ARRAY_SIZE (amd64_sol2_gregset32_reg_offset);
-  amd64_native_gregset64_reg_offset = amd64_sol2_gregset64_reg_offset;
-  amd64_native_gregset64_num_regs =
-    ARRAY_SIZE (amd64_sol2_gregset64_reg_offset);
 #endif
 
   add_target (t);
diff --git a/gdb/testsuite/gdb.arch/system-gcore.exp b/gdb/testsuite/gdb.arch/system-gcore.exp
new file mode 100644
index 0000000..9c8c911
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/system-gcore.exp
@@ -0,0 +1,238 @@
+# Copyright 2010
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+if $tracelevel then {
+	strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+if { ![istarget i?86-*-linux*] && ![istarget x86_64-*-linux* ] } {
+    verbose "Skipping system register gcore tests."
+    return
+}
+
+set testfile "system-gcore"
+set srcfile  gcore.c
+set binfile  ${objdir}/${subdir}/${testfile}
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+     untested system-gcore.exp
+     return -1
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Does this gdb support gcore?
+send_gdb "help gcore\n"
+gdb_expect {
+    -re "Undefined command: .gcore.*$gdb_prompt $" {
+	# gcore command not supported -- nothing to test here.
+	unsupported "gdb does not support gcore on this target"
+	return -1;
+    }
+    -re "Save a core file .*$gdb_prompt $" {
+	pass "help gcore"
+    }
+    -re ".*$gdb_prompt $" {
+	fail "help gcore"
+    }
+    timeout {
+	fail "help gcore (timeout)"
+    }
+}
+
+if { ! [ runto_main ] } then {
+    untested system-gcore.exp
+    return -1
+}
+
+proc capture_command_output { command prefix } {
+    global gdb_prompt
+    global expect_out
+
+    set output_string ""
+    gdb_test_multiple "$command" "capture_command_output for $command" {
+	-re "${command}\[\r\n\]+${prefix}(.*)\[\r\n\]+$gdb_prompt $" {
+	    set output_string $expect_out(1,string)
+	}
+    }
+    return $output_string
+}
+
+gdb_test "break terminal_func" "Breakpoint .* at .*${srcfile}, line .*" \
+	"set breakpoint at terminal_func"
+
+gdb_test "continue" "Breakpoint .* terminal_func.*" \
+	"continue to terminal_func"
+
+set print_prefix ".\[0123456789\]* = "
+
+set pre_corefile_backtrace [capture_command_output "backtrace" ""]
+set pre_corefile_regs [capture_command_output "info registers" ""]
+set pre_corefile_allregs [capture_command_output "info all-reg" ""]
+set pre_corefile_sysregs [capture_command_output "info reg system" ""]
+set pre_corefile_static_array \
+	[capture_command_output "print static_array" "$print_prefix"]
+set pre_corefile_uninit_array \
+	[capture_command_output "print un_initialized_array" "$print_prefix"]
+set pre_corefile_heap_string \
+	[capture_command_output "print heap_string" "$print_prefix"]
+set pre_corefile_local_array \
+	[capture_command_output "print array_func::local_array" "$print_prefix"]
+set pre_corefile_extern_array \
+	[capture_command_output "print extern_array" "$print_prefix"]
+
+set escapedfilename [string_to_regexp ${objdir}/${subdir}/gcore.test]
+
+set core_supported 0
+gdb_test_multiple "gcore ${objdir}/${subdir}/gcore.test" \
+	"save a corefile" \
+{
+  -re "Saved corefile ${escapedfilename}\[\r\n\]+$gdb_prompt $" {
+    pass "save a corefile"
+    global core_supported
+    set core_supported 1
+  }
+  -re "Can't create a corefile\[\r\n\]+$gdb_prompt $" {
+    unsupported "save a corefile"
+    global core_supported
+    set core_supported 0
+  }
+}
+
+if {!$core_supported} {
+  return -1
+}
+
+# Now restart gdb and load the corefile.
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+send_gdb "core ${objdir}/${subdir}/gcore.test\n"
+gdb_expect {
+    -re ".* is not a core dump:.*$gdb_prompt $" {
+	fail "re-load generated corefile (bad file format)"
+	# No use proceeding from here.
+	return;	
+    }
+    -re ".*: No such file or directory.*$gdb_prompt $" {
+	fail "re-load generated corefile (file not found)"
+	# No use proceeding from here.
+	return;	
+    }
+    -re ".*Couldn't find .* registers in core file.*$gdb_prompt $" {
+	fail "re-load generated corefile (incomplete note section)"
+    }
+    -re "Core was generated by .*$gdb_prompt $" {
+	pass "re-load generated corefile"
+    }
+    -re ".*$gdb_prompt $" {
+	fail "re-load generated corefile"
+    }
+    timeout {
+	fail "re-load generated corefile (timeout)"
+    }
+}
+
+send_gdb "where\n"
+gdb_expect_list "where in corefile" ".*$gdb_prompt $" {
+    ".*\[\r\n\]+#0 .* terminal_func \\(\\) at "
+    ".*\[\r\n\]+#1 .* array_func \\(\\) at "
+    ".*\[\r\n\]+#2 .* factorial_func \\(value=1\\) at "
+    ".*\[\r\n\]+#3 .* factorial_func \\(value=2\\) at "
+    ".*\[\r\n\]+#4 .* factorial_func \\(value=3\\) at "
+    ".*\[\r\n\]+#5 .* factorial_func \\(value=4\\) at "
+    ".*\[\r\n\]+#6 .* factorial_func \\(value=5\\) at "
+    ".*\[\r\n\]+#7 .* factorial_func \\(value=6\\) at "
+    ".*\[\r\n\]+#8 .* main \\(.*\\) at "
+}
+
+set post_corefile_regs [capture_command_output "info registers" ""]
+if ![string compare $pre_corefile_regs $post_corefile_regs] then {
+    pass "corefile restored general registers"
+} else {
+    fail "corefile restored general registers"
+}
+
+set post_corefile_allregs [capture_command_output "info all-reg" ""]
+if ![string compare $pre_corefile_allregs $post_corefile_allregs] then {
+    pass "corefile restored all registers"
+} else {
+    fail "corefile restored all registers"
+}
+
+set post_corefile_sysregs [capture_command_output "info reg system" ""]
+if ![string compare $pre_corefile_sysregs $post_corefile_sysregs] then {
+    pass "corefile restored system registers"
+} else {
+    fail "corefile restored system registers"
+}
+
+set post_corefile_extern_array \
+	[capture_command_output "print extern_array" "$print_prefix"]
+if ![string compare $pre_corefile_extern_array $post_corefile_extern_array]  {
+    pass "corefile restored extern array"
+} else {
+    fail "corefile restored extern array"
+}
+
+set post_corefile_static_array \
+	[capture_command_output "print static_array" "$print_prefix"]
+if ![string compare $pre_corefile_static_array $post_corefile_static_array]  {
+    pass "corefile restored static array"
+} else {
+    fail "corefile restored static array"
+}
+
+set post_corefile_uninit_array \
+	[capture_command_output "print un_initialized_array" "$print_prefix"]
+if ![string compare $pre_corefile_uninit_array $post_corefile_uninit_array]  {
+    pass "corefile restored un-initialized array"
+} else {
+    fail "corefile restored un-initialized array"
+}
+
+set post_corefile_heap_string \
+	[capture_command_output "print heap_string" "$print_prefix"]
+if ![string compare $pre_corefile_heap_string $post_corefile_heap_string]  {
+    pass "corefile restored heap array"
+} else {
+    fail "corefile restored heap array"
+}
+
+set post_corefile_local_array \
+	[capture_command_output "print array_func::local_array" "$print_prefix"]
+if ![string compare $pre_corefile_local_array $post_corefile_local_array]  {
+    pass "corefile restored stack array"
+} else {
+    fail "corefile restored stack array"
+}
+
+set post_corefile_backtrace [capture_command_output "backtrace" ""]
+if ![string compare $pre_corefile_backtrace $post_corefile_backtrace]  {
+    pass "corefile restored backtrace"
+} else {
+    fail "corefile restored backtrace"
+}
--- /dev/null	2010-04-15 07:53:19.585799905 -0700
+++ gdb/gdb/testsuite/gdb.arch/gcore.c	2010-04-17 08:48:12.000000000 -0700
@@ -0,0 +1,70 @@
+/* Copyright 2002, 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/*
+ * Test GDB's ability to save and reload a corefile.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+int extern_array[4] = {1, 2, 3, 4};
+static int static_array[4] = {5, 6, 7, 8};
+static int un_initialized_array[4];
+static char *heap_string;
+
+void 
+terminal_func ()
+{
+  return;
+}
+
+void
+array_func ()
+{
+  int local_array[4];
+  int i;
+
+  heap_string = (char *) malloc (80);
+  strcpy (heap_string, "I'm a little teapot, short and stout...");
+  for (i = 0; i < 4; i++)
+    {
+      un_initialized_array[i] = extern_array[i] + 8;
+      local_array[i] = extern_array[i] + 12;
+    }
+  terminal_func ();
+}
+
+#ifdef PROTOTYPES
+int factorial_func (int value)
+#else
+int factorial_func (value)
+     int value;
+#endif
+{
+  if (value > 1) {
+    value *= factorial_func (value - 1);
+  }
+  array_func ();
+  return (value);
+}
+
+main()
+{
+  factorial_func (6);
+  return 0;
+}

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

* Re: PATCH: PR corefiles/11511: gcore doesn't work with orig_rax on  Linux/amd64
  2010-04-17 16:11 PATCH: PR corefiles/11511: gcore doesn't work with orig_rax on Linux/amd64 H.J. Lu
@ 2010-04-17 16:25 ` Mark Kettenis
  2010-04-17 18:50   ` H.J. Lu
  0 siblings, 1 reply; 8+ messages in thread
From: Mark Kettenis @ 2010-04-17 16:25 UTC (permalink / raw)
  To: hjl.tools; +Cc: gdb-patches

> Date: Sat, 17 Apr 2010 09:11:15 -0700
> From: "H.J. Lu" <hongjiu.lu@intel.com>
> 
> This patch adds orig_rax support to amd64_linux_gregset_reg_offset.
> amd64 has both tdep->gregset_reg_offset/tdep->gregset_num_regs and
> amd64_native_gregset64_reg_offset/amd64_native_gregset64_num_regs.  They 
> are identical. There is no need to keep both.  This patch also removes
> amd64_native_gregset64_reg_offset/amd64_native_gregset64_num_regs. OK
> to install?

No.  I want to keep the -nat.c and -tdep.c code separate.

The bit below is ok, but please drop the other bits.

> 	* amd64-linux-tdep.c (amd64_linux_gregset_reg_offset): Support
> 	orig_rax.

> diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
> index 1205e31..f249d5d 100644
> --- a/gdb/amd64-linux-tdep.c
> +++ b/gdb/amd64-linux-tdep.c
> @@ -87,7 +87,14 @@ static int amd64_linux_gregset_reg_offset[] =
>    23 * 8,			/* %ds */
>    24 * 8,			/* %es */
>    25 * 8,			/* %fs */
> -  26 * 8			/* %gs */
> +  26 * 8,			/* %gs */
> +  -1, -1, -1, -1, -1, -1, -1, -1,
> +  -1, -1, -1, -1, -1, -1, -1, -1,
> +  -1, -1, -1, -1, -1, -1, -1, -1,
> +  -1, -1, -1, -1, -1, -1, -1, -1, -1,
> +  -1, -1, -1, -1, -1, -1, -1, -1,
> +  -1, -1, -1, -1, -1, -1, -1, -1,
> +  15 * 8			/* "orig_rax" */
>  };
>  \f
>  

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

* Re: PATCH: PR corefiles/11511: gcore doesn't work with orig_rax on   Linux/amd64
  2010-04-17 16:25 ` Mark Kettenis
@ 2010-04-17 18:50   ` H.J. Lu
  2010-04-18 21:33     ` Mark Kettenis
  0 siblings, 1 reply; 8+ messages in thread
From: H.J. Lu @ 2010-04-17 18:50 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: gdb-patches

On Sat, Apr 17, 2010 at 9:25 AM, Mark Kettenis <mark.kettenis@xs4all.nl> wrote:
>> Date: Sat, 17 Apr 2010 09:11:15 -0700
>> From: "H.J. Lu" <hongjiu.lu@intel.com>
>>
>> This patch adds orig_rax support to amd64_linux_gregset_reg_offset.
>> amd64 has both tdep->gregset_reg_offset/tdep->gregset_num_regs and
>> amd64_native_gregset64_reg_offset/amd64_native_gregset64_num_regs.  They
>> are identical. There is no need to keep both.  This patch also removes
>> amd64_native_gregset64_reg_offset/amd64_native_gregset64_num_regs. OK
>> to install?
>
> No.  I want to keep the -nat.c and -tdep.c code separate.

Can I replace amd64_linux_gregset64_reg_offset with
amd64_linux_gregset_reg_offset, like amd64nbsd-nat.c
and amd64obsd-nat.c?

Thanks.

H.J.
--
> The bit below is ok, but please drop the other bits.
>
>>       * amd64-linux-tdep.c (amd64_linux_gregset_reg_offset): Support
>>       orig_rax.
>
>> diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
>> index 1205e31..f249d5d 100644
>> --- a/gdb/amd64-linux-tdep.c
>> +++ b/gdb/amd64-linux-tdep.c
>> @@ -87,7 +87,14 @@ static int amd64_linux_gregset_reg_offset[] =
>>    23 * 8,                    /* %ds */
>>    24 * 8,                    /* %es */
>>    25 * 8,                    /* %fs */
>> -  26 * 8                     /* %gs */
>> +  26 * 8,                    /* %gs */
>> +  -1, -1, -1, -1, -1, -1, -1, -1,
>> +  -1, -1, -1, -1, -1, -1, -1, -1,
>> +  -1, -1, -1, -1, -1, -1, -1, -1,
>> +  -1, -1, -1, -1, -1, -1, -1, -1, -1,
>> +  -1, -1, -1, -1, -1, -1, -1, -1,
>> +  -1, -1, -1, -1, -1, -1, -1, -1,
>> +  15 * 8                     /* "orig_rax" */
>>  };
>>
>>
>



-- 
H.J.

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

* Re: PATCH: PR corefiles/11511: gcore doesn't work with orig_rax on   Linux/amd64
  2010-04-17 18:50   ` H.J. Lu
@ 2010-04-18 21:33     ` Mark Kettenis
  2010-04-19 15:26       ` Daniel Jacobowitz
  2010-04-19 17:21       ` H.J. Lu
  0 siblings, 2 replies; 8+ messages in thread
From: Mark Kettenis @ 2010-04-18 21:33 UTC (permalink / raw)
  To: hjl.tools; +Cc: gdb-patches

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1438 bytes --]

> Date: Sat, 17 Apr 2010 11:50:11 -0700
> From: "H.J. Lu" <hjl.tools@gmail.com>
> 
> On Sat, Apr 17, 2010 at 9:25 AM, Mark Kettenis <mark.kettenis@xs4all.nl> wrote:
> >> Date: Sat, 17 Apr 2010 09:11:15 -0700
> >> From: "H.J. Lu" <hongjiu.lu@intel.com>
> >>
> >> This patch adds orig_rax support to amd64_linux_gregset_reg_offset.
> >> amd64 has both tdep->gregset_reg_offset/tdep->gregset_num_regs and
> >> amd64_native_gregset64_reg_offset/amd64_native_gregset64_num_regs.  They
> >> are identical. There is no need to keep both.  This patch also removes
> >> amd64_native_gregset64_reg_offset/amd64_native_gregset64_num_regs. OK
> >> to install?
> >
> > No.  I want to keep the -nat.c and -tdep.c code separate.
> 
> Can I replace amd64_linux_gregset64_reg_offset with
> amd64_linux_gregset_reg_offset, like amd64nbsd-nat.c
> and amd64obsd-nat.c?

We can discuss that, yes.  The way the code is organized now, at least
native debugging will continue to work if the layout of the trap frame
in the Linux kernel were to change.  At least in the past there was
some fear that this would happen.  That danger is probably small; I'm
not even sure if the data structure for PTRACE_GETREGS is even linked
to the trap frame layout anymore.

Of course the benefit of doing so is that if the kernel ABI is ever
broken GDB will completely stop working on Linux instead of just being
partly broken.

Any other people have an opinion about this?

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

* Re: PATCH: PR corefiles/11511: gcore doesn't work with orig_rax on    Linux/amd64
  2010-04-18 21:33     ` Mark Kettenis
@ 2010-04-19 15:26       ` Daniel Jacobowitz
  2010-04-19 17:21       ` H.J. Lu
  1 sibling, 0 replies; 8+ messages in thread
From: Daniel Jacobowitz @ 2010-04-19 15:26 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: hjl.tools, gdb-patches

On Sun, Apr 18, 2010 at 11:32:52PM +0200, Mark Kettenis wrote:
> Any other people have an opinion about this?

I think that it made a lot of sense to be robust about this when the
amd64 port was new, but it isn't necessary any more.

-- 
Daniel Jacobowitz
CodeSourcery

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

* Re: PATCH: PR corefiles/11511: gcore doesn't work with orig_rax on   Linux/amd64
  2010-04-18 21:33     ` Mark Kettenis
  2010-04-19 15:26       ` Daniel Jacobowitz
@ 2010-04-19 17:21       ` H.J. Lu
  2010-04-19 17:28         ` H. Peter Anvin
  1 sibling, 1 reply; 8+ messages in thread
From: H.J. Lu @ 2010-04-19 17:21 UTC (permalink / raw)
  To: Mark Kettenis, H. Peter Anvin; +Cc: gdb-patches

On Sun, Apr 18, 2010 at 2:32 PM, Mark Kettenis <mark.kettenis@xs4all.nl> wrote:
>> Date: Sat, 17 Apr 2010 11:50:11 -0700
>> From: "H.J. Lu" <hjl.tools@gmail.com>
>>
>> On Sat, Apr 17, 2010 at 9:25 AM, Mark Kettenis <mark.kettenis@xs4all.nl> wrote:
>> >> Date: Sat, 17 Apr 2010 09:11:15 -0700
>> >> From: "H.J. Lu" <hongjiu.lu@intel.com>
>> >>
>> >> This patch adds orig_rax support to amd64_linux_gregset_reg_offset.
>> >> amd64 has both tdep->gregset_reg_offset/tdep->gregset_num_regs and
>> >> amd64_native_gregset64_reg_offset/amd64_native_gregset64_num_regs.  They
>> >> are identical. There is no need to keep both.  This patch also removes
>> >> amd64_native_gregset64_reg_offset/amd64_native_gregset64_num_regs. OK
>> >> to install?
>> >
>> > No.  I want to keep the -nat.c and -tdep.c code separate.
>>
>> Can I replace amd64_linux_gregset64_reg_offset with
>> amd64_linux_gregset_reg_offset, like amd64nbsd-nat.c
>> and amd64obsd-nat.c?
>
> We can discuss that, yes.  The way the code is organized now, at least
> native debugging will continue to work if the layout of the trap frame
> in the Linux kernel were to change.  At least in the past there was
> some fear that this would happen.  That danger is probably small; I'm
> not even sure if the data structure for PTRACE_GETREGS is even linked
> to the trap frame layout anymore.
>
> Of course the benefit of doing so is that if the kernel ABI is ever
> broken GDB will completely stop working on Linux instead of just being
> partly broken.
>
> Any other people have an opinion about this?
>

I am CCing Peter, who is the Linux x86 kernel maintainer.

We have 2 general-purpose register maps in GDB. One is in nat.c:

/* Mapping between the general-purpose registers in GNU/Linux x86-64
   `struct user' format and GDB's register cache layout.  */

static int amd64_linux_gregset64_reg_offset[] =

It is used for reading/writing registers from/to kernel. One is in tdep.c:

/* Mapping between the general-purpose registers in `struct user'
   format and GDB's register cache layout.  */

/* From <sys/reg.h>.  */
static int amd64_linux_gregset_reg_offset[] =

It is use for reading/writing core dump.

Both are mappings between `struct user'  and  GDB's register cache.
It is very unlikely that the current x86 Linux kernel ABI for accessing
 `struct user' will change.  If the kernel ABI does need to change for
whatever reason, the new interface will be introduced.

This applies to both i386 and x86-64 Linux kernel. I'd like to keep
a single map between the general-purpose registers in `struct user'
format and GDB's register cache for i386/x86-64 Linux. Will such
a patch acceptable?

Thanks.


-- 
H.J.

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

* Re: PATCH: PR corefiles/11511: gcore doesn't work with orig_rax on   Linux/amd64
  2010-04-19 17:21       ` H.J. Lu
@ 2010-04-19 17:28         ` H. Peter Anvin
  2010-04-20 22:17           ` Roland McGrath
  0 siblings, 1 reply; 8+ messages in thread
From: H. Peter Anvin @ 2010-04-19 17:28 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Mark Kettenis, gdb-patches

On 04/19/2010 10:21 AM, H.J. Lu wrote:
> 
> I am CCing Peter, who is the Linux x86 kernel maintainer.
> 

Also adding Roland McGrath.

> We have 2 general-purpose register maps in GDB. One is in nat.c:
> 
> /* Mapping between the general-purpose registers in GNU/Linux x86-64
>    `struct user' format and GDB's register cache layout.  */
> 
> static int amd64_linux_gregset64_reg_offset[] =
> 
> It is used for reading/writing registers from/to kernel. One is in tdep.c:
> 
> /* Mapping between the general-purpose registers in `struct user'
>    format and GDB's register cache layout.  */
> 
> /* From <sys/reg.h>.  */
> static int amd64_linux_gregset_reg_offset[] =
> 
> It is use for reading/writing core dump.
> 
> Both are mappings between `struct user'  and  GDB's register cache.
> It is very unlikely that the current x86 Linux kernel ABI for accessing
>  `struct user' will change.  If the kernel ABI does need to change for
> whatever reason, the new interface will be introduced.
> 
> This applies to both i386 and x86-64 Linux kernel. I'd like to keep
> a single map between the general-purpose registers in `struct user'
> format and GDB's register cache for i386/x86-64 Linux. Will such
> a patch acceptable?
> 

struct user will not change, at least not for i386/x86-64.  New
additions will be done via regsets, i.e. PTRACE_GETREGSET.  I can't
speak for the embedded architectures, obviously, but they should do
something similar.

	-hpa

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

* Re: PATCH: PR corefiles/11511: gcore doesn't work with orig_rax on   Linux/amd64
  2010-04-19 17:28         ` H. Peter Anvin
@ 2010-04-20 22:17           ` Roland McGrath
  0 siblings, 0 replies; 8+ messages in thread
From: Roland McGrath @ 2010-04-20 22:17 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: H.J. Lu, Mark Kettenis, gdb-patches

The "struct user" layout per se is only used for PTRACE_PEEKUSR/POKEUSR.
(And for a.out core dumps, for which support still existing is questionable.)

On x86, the only thing for which PEEKUSR/POKEUSR is the recommended (and
sole available) method of access is u_debugreg.  That use is the only thing
for which you really need to know "struct user" offsets per se.  If you do
use PEEKUSR/POKEUSR for general register access, the leading portion of
"struct user" is "struct user_regs_struct".  Only that leading portion and
u_debugreg are accessible via PEEKUSR/POKEUSR.

On x86, "struct user_regs_struct" matches the official "primary regset"
layout.  This is what PTRACE_GETREGS/SETREGS uses (on x86--the definitions
of such "legacy" ptrace requests are unfortunately quite idiosyncratic on
each arch beyond the arch's official regset layouts).

In Linux across the board (since 2.6.25 or so), there is one official
canonical layout for each "regset" and this matches the formats used in ELF
core files.  We use the NT_* type codes to refer to which regset you mean.
The "primary regset" layout corresponds to the NT_PRSTATUS note's pr_reg
field--on all machines, that's the one with the general registers.  All
other regsets exactly match the layout of the whole note segment
(NT_PRFPREG, etc.) as found in core files.  The expectation is that any and
all new facilities will use these formats.  Any old ptrace requests that
use different layouts are only kept for backward compatibility.  When new
kinds of register data are added, this will add a new NT_* code and
corresponding layout that is used both for core dumps and for debugging.

In the most recent Linux (only since 2.6.33), there is a generic pair of
requests, PTRACE_GETREGSET and PTRACE_SETREGSET.  This is now the preferred
way to access all user register data.  (The x86 debug registers and similar
things do not form part of the state visible to the user-mode thread and
hence are not part of any "regset".)  This is already the only method for
new kinds of register data such as NT_X86_XSTATE (the only way to get the
high halves of ymm registers, for example).  For all machines, if they CC
me as generic ptrace maintainer, I'll NAK any additions of new one-off
requests in favor of making PTRACE_GETREGSET work right for each arch.
Those requests take the NT_* code to select which regset you want.

These new requests have another wrinkle for biarch machines like x86.
This may be better or worse for you in practice, depending on how you
organize things in your application.  Previous ptrace requests always
referred to the tracer's view of the machine regardless of the tracee's
view.  That is, a 64-bit process calling ptrace always sees the 64-bit
register formats for PTRACE_PEEKUSR, PTRACE_GETREGS, etc.  When dealing
with a 32-bit tracee you just have to know how to interpret a subset of
the 64-bit data as equivalent to 32-bit register data.  In the new
requests, we take the opposite tack.  PTRACE_[GS]ETREGSET always refer
to the tracee's view of its regsets, regardless of what kind of process
makes the ptrace calls.  That is, a 64-bit process tracing a 32-bit
process sees the 32-bit register formats and a 32-bit process tracing a
64-bit process sees the 64-bit register formats.  This has some
advantages and one arcane disadvantage I can elaborate on if you want.


Thanks,
Roland

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

end of thread, other threads:[~2010-04-20 22:17 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-17 16:11 PATCH: PR corefiles/11511: gcore doesn't work with orig_rax on Linux/amd64 H.J. Lu
2010-04-17 16:25 ` Mark Kettenis
2010-04-17 18:50   ` H.J. Lu
2010-04-18 21:33     ` Mark Kettenis
2010-04-19 15:26       ` Daniel Jacobowitz
2010-04-19 17:21       ` H.J. Lu
2010-04-19 17:28         ` H. Peter Anvin
2010-04-20 22:17           ` Roland McGrath

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).