gdb/
authorDaniel Jacobowitz <drow@false.org>
Sat, 19 Aug 2006 15:15:18 +0000 (15:15 +0000)
committerDaniel Jacobowitz <drow@false.org>
Sat, 19 Aug 2006 15:15:18 +0000 (15:15 +0000)
* Makefile.in (amd64_linux_tdep_h): New.
(amd64-linux-nat.o, amd64-linux-tdep.o): Update.
* amd64-linux-nat.c (amd64_linux_gregset64_reg_offset): Add
ORIG_RAX.
(_initialize_amd64_linux_nat): Set amd64_native_gregset64_num_regs.
* amd64-linux-tdep.c (amd64_linux_register_name)
(amd64_linux_register_type, amd64_linux_register_reggroup_p)
(amd64_linux_write_pc): New.
(amd64_linux_init_abi): Use them, and update num_regs.
* amd64-linux-tdep.h: New file.
* amd64-tdep.c (amd64_register_name, amd64_register_type): Make
public.
* amd64-tdep.h (amd64_register_name, amd64_register_type): New
prototypes.

* regformats/reg-x86-64-linux.dat: New file.
gdb/testsuite/
* Makefile.in (clean): Clean reg-x86-64-linux.c.
(reg-x86-64-linux.o, reg-x86-64-linux.c): New.
* configure.srv (x86_64-*-linux*): Use reg-x86-64-linux.o.
* linux-x86-64-low.c (x86_64_regmap): Include ORIG_RAX.
(x86_64_fill_gregset, x86_64_store_gregset): Skip floating
point registers.

12 files changed:
gdb/ChangeLog
gdb/Makefile.in
gdb/amd64-linux-nat.c
gdb/amd64-linux-tdep.c
gdb/amd64-linux-tdep.h [new file with mode: 0644]
gdb/amd64-tdep.c
gdb/amd64-tdep.h
gdb/gdbserver/ChangeLog
gdb/gdbserver/Makefile.in
gdb/gdbserver/configure.srv
gdb/gdbserver/linux-x86-64-low.c
gdb/regformats/reg-x86-64-linux.dat [new file with mode: 0644]

index 908e7e48446506d5c723de77c4b359cc033301d6..b3f306c0f71e6473d3f9ab579e4298d7f35a747e 100644 (file)
@@ -1,3 +1,22 @@
+2006-08-19  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * Makefile.in (amd64_linux_tdep_h): New.
+       (amd64-linux-nat.o, amd64-linux-tdep.o): Update.
+       * amd64-linux-nat.c (amd64_linux_gregset64_reg_offset): Add
+       ORIG_RAX.
+       (_initialize_amd64_linux_nat): Set amd64_native_gregset64_num_regs.
+       * amd64-linux-tdep.c (amd64_linux_register_name)
+       (amd64_linux_register_type, amd64_linux_register_reggroup_p)
+       (amd64_linux_write_pc): New.
+       (amd64_linux_init_abi): Use them, and update num_regs.
+       * amd64-linux-tdep.h: New file.
+       * amd64-tdep.c (amd64_register_name, amd64_register_type): Make
+       public.
+       * amd64-tdep.h (amd64_register_name, amd64_register_type): New
+       prototypes.
+
+       * regformats/reg-x86-64-linux.dat: New file.
+
 2006-08-18  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * infrun.c (handle_inferior_event): Check the current frame ID
index 797492046ca9b139aec07e2d1485e09839eb89f8..c51ac73161de77f1699d7cfe23bbed462f98091c 100644 (file)
@@ -638,6 +638,7 @@ ada_lang_h = ada-lang.h $(value_h) $(gdbtypes_h) $(breakpoint_h)
 ada_lex_c = ada-lex.c $(gdb_string_h)
 alphabsd_tdep_h = alphabsd-tdep.h
 alpha_tdep_h = alpha-tdep.h
+amd64_linux_tdep_h = amd64-linux-tdep.h
 amd64_nat_h = amd64-nat.h
 amd64_tdep_h = amd64-tdep.h $(i386_tdep_h)
 annotate_h = annotate.h $(symtab_h) $(gdbtypes_h)
@@ -1738,10 +1739,10 @@ amd64fbsd-tdep.o: amd64fbsd-tdep.c $(defs_h) $(arch_utils_h) $(frame_h) \
 amd64-linux-nat.o: amd64-linux-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) \
        $(regcache_h) $(linux_nat_h) $(gdb_assert_h) $(gdb_string_h) \
        $(gdb_proc_service_h) $(gregset_h) $(amd64_tdep_h) \
-       $(i386_linux_tdep_h) $(amd64_nat_h) $(target_h)
+       $(i386_linux_tdep_h) $(amd64_nat_h) $(target_h) $(amd64_linux_tdep_h)
 amd64-linux-tdep.o: amd64-linux-tdep.c $(defs_h) $(frame_h) $(gdbcore_h) \
        $(regcache_h) $(osabi_h) $(symtab_h) $(gdb_string_h) $(amd64_tdep_h) \
-       $(solib_svr4_h)
+       $(solib_svr4_h) $(gdbtypes_h) $(reggroups_h) $(amd64_linux_tdep_h)
 amd64-nat.o: amd64-nat.c $(defs_h) $(gdbarch_h) $(regcache_h) \
        $(gdb_assert_h) $(gdb_string_h) $(i386_tdep_h) $(amd64_tdep_h)
 amd64nbsd-nat.o: amd64nbsd-nat.c $(defs_h) $(target_h) $(gdb_assert_h) \
index b4a71125a3e27a26bee35724a421dec4213fd8b8..fca05c8a5aea5c7bd024a56fa5e521ec1f2dbb32 100644 (file)
@@ -26,6 +26,7 @@
 #include "gdbcore.h"
 #include "regcache.h"
 #include "linux-nat.h"
+#include "amd64-linux-tdep.h"
 
 #include "gdb_assert.h"
 #include "gdb_string.h"
@@ -68,7 +69,12 @@ static int amd64_linux_gregset64_reg_offset[] =
   RIP * 8, EFLAGS * 8,         /* %rip, %eflags */
   CS * 8, SS * 8,              /* %cs, %ss */
   DS * 8, ES * 8,              /* %ds, %es */
-  FS * 8, GS * 8               /* %fs, %gs */
+  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,
+  ORIG_RAX * 8
 };
 \f
 
@@ -382,6 +388,7 @@ _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);
index 9fa01739bc306775d9b6b7890f8893de25a49b3e..316b1f3faf8d047307db269089b33ff531035c18 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for GNU/Linux x86-64.
 
-   Copyright (C) 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
    Contributed by Jiri Smid, SuSE Labs.
 
    This file is part of GDB.
@@ -26,6 +26,9 @@
 #include "regcache.h"
 #include "osabi.h"
 #include "symtab.h"
+#include "gdbtypes.h"
+#include "reggroups.h"
+#include "amd64-linux-tdep.h"
 
 #include "gdb_string.h"
 
@@ -199,6 +202,61 @@ static int amd64_linux_sc_reg_offset[] =
   -1                           /* %gs */
 };
 
+/* Replacement register functions which know about %orig_rax.  */
+
+static const char *
+amd64_linux_register_name (int reg)
+{
+  if (reg == AMD64_LINUX_ORIG_RAX_REGNUM)
+    return "orig_rax";
+
+  return amd64_register_name (reg);
+}
+
+static struct type *
+amd64_linux_register_type (struct gdbarch *gdbarch, int reg)
+{
+  if (reg == AMD64_LINUX_ORIG_RAX_REGNUM)
+    return builtin_type_int64;
+
+  return amd64_register_type (gdbarch, reg);
+}
+
+static int
+amd64_linux_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
+                                struct reggroup *group)
+{ 
+  if (regnum == AMD64_LINUX_ORIG_RAX_REGNUM)
+    return (group == system_reggroup
+            || group == save_reggroup
+            || group == restore_reggroup);
+  return default_register_reggroup_p (gdbarch, regnum, group);
+}
+
+/* Set the program counter for process PTID to PC.  */
+
+static void
+amd64_linux_write_pc (CORE_ADDR pc, ptid_t ptid)
+{
+  write_register_pid (AMD64_RIP_REGNUM, pc, ptid);
+
+  /* We must be careful with modifying the program counter.  If we
+     just interrupted a system call, the kernel might try to restart
+     it when we resume the inferior.  On restarting the system call,
+     the kernel will try backing up the program counter even though it
+     no longer points at the system call.  This typically results in a
+     SIGSEGV or SIGILL.  We can prevent this by writing `-1' in the
+     "orig_rax" pseudo-register.
+
+     Note that "orig_rax" is saved when setting up a dummy call frame.
+     This means that it is properly restored when that frame is
+     popped, and that the interrupted system call will be restarted
+     when we resume the inferior on return from a function call from
+     within GDB.  In all other cases the system call will not be
+     restarted.  */
+  write_register_pid (AMD64_LINUX_ORIG_RAX_REGNUM, -1, ptid);
+}
+
 static void
 amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -219,6 +277,13 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_solib_svr4_fetch_link_map_offsets
     (gdbarch, svr4_lp64_fetch_link_map_offsets);
 
+  /* Add the %orig_rax register used for syscall restarting.  */
+  set_gdbarch_write_pc (gdbarch, amd64_linux_write_pc);
+  set_gdbarch_num_regs (gdbarch, AMD64_LINUX_NUM_REGS);
+  set_gdbarch_register_name (gdbarch, amd64_linux_register_name);
+  set_gdbarch_register_type (gdbarch, amd64_linux_register_type);
+  set_gdbarch_register_reggroup_p (gdbarch, amd64_linux_register_reggroup_p);
+
   /* Enable TLS support.  */
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
                                              svr4_fetch_objfile_link_map);
diff --git a/gdb/amd64-linux-tdep.h b/gdb/amd64-linux-tdep.h
new file mode 100644 (file)
index 0000000..4a5778d
--- /dev/null
@@ -0,0 +1,36 @@
+/* Target-dependent code for GNU/Linux AMD64.
+
+   Copyright (C) 2006 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 2 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, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#ifndef AMD64_LINUX_TDEP_H
+#define AMD64_LINUX_TDEP_H
+
+/* Like for i386 GNU/Linux, there is an extra "register"
+   used to control syscall restarting.  */
+
+/* Register number for the "orig_rax" register.  If this register
+   contains a value >= 0 it is interpreted as the system call number
+   that the kernel is supposed to restart.  */
+#define AMD64_LINUX_ORIG_RAX_REGNUM (AMD64_MXCSR_REGNUM + 1)
+
+/* Total number of registers for GNU/Linux.  */
+#define AMD64_LINUX_NUM_REGS (AMD64_LINUX_ORIG_RAX_REGNUM + 1)
+
+#endif /* amd64-linux-tdep.h */
index 647edcd97b90844879118211ab71004b6a533678..b39c839e2aa2bd2ac2dc701f28e3925ca27d778e 100644 (file)
@@ -129,7 +129,7 @@ static struct amd64_register_info const amd64_register_info[] =
 
 /* Return the name of register REGNUM.  */
 
-static const char *
+const char *
 amd64_register_name (int regnum)
 {
   if (regnum >= 0 && regnum < AMD64_NUM_REGS)
@@ -141,7 +141,7 @@ amd64_register_name (int regnum)
 /* Return the GDB type object for the "standard" data type of data in
    register REGNUM. */
 
-static struct type *
+struct type *
 amd64_register_type (struct gdbarch *gdbarch, int regnum)
 {
   gdb_assert (regnum >= 0 && regnum < AMD64_NUM_REGS);
index f2670af2f69e6cd1b0c194357a4259827448250d..0fc0f5b11eec2a6ce1221230f774ef6ef28df756 100644 (file)
@@ -64,6 +64,12 @@ enum amd64_regnum
 
 extern void amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch);
 
+/* Functions from amd64-tdep.c which may be needed on architectures
+   with extra registers.  */
+
+extern const char *amd64_register_name (int regnum);
+extern struct type *amd64_register_type (struct gdbarch *gdbarch, int regnum);
+
 /* Fill register REGNUM in REGCACHE with the appropriate
    floating-point or SSE register value from *FXSAVE.  If REGNUM is
    -1, do this for all registers.  This function masks off any of the
index a5a735a12162c3c0fba0fc546299092d3dcdd267..25b7ed55619ce886ef1f1caec6b72bd5b515630b 100644 (file)
@@ -1,3 +1,12 @@
+2006-08-19  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * Makefile.in (clean): Clean reg-x86-64-linux.c.
+       (reg-x86-64-linux.o, reg-x86-64-linux.c): New.
+       * configure.srv (x86_64-*-linux*): Use reg-x86-64-linux.o.
+       * linux-x86-64-low.c (x86_64_regmap): Include ORIG_RAX.
+       (x86_64_fill_gregset, x86_64_store_gregset): Skip floating
+       point registers.
+
 2006-08-08  Richard Sandiford  <richard@codesourcery.com>
 
        * server.c (terminal_fd): New variable.
index 01642c802ac1721edca1fc3b232d86a27f224146..f443a2880267cd0ee6dfb2c5142a41f5c124b43c 100644 (file)
@@ -206,7 +206,7 @@ clean:
        rm -f gdbserver gdbreplay core make.log
        rm -f reg-arm.c reg-i386.c reg-ia64.c reg-m32r.c reg-m68k.c reg-mips.c
        rm -f reg-ppc.c reg-sh.c reg-x86-64.c reg-i386-linux.c
-       rm -f reg-cris.c reg-crisv32.c
+       rm -f reg-cris.c reg-crisv32.c reg-x86-64-linux.c
 
 maintainer-clean realclean distclean: clean
        rm -f nm.h tm.h xm.h config.status config.h stamp-h config.log
@@ -334,5 +334,8 @@ reg-sh.c : $(srcdir)/../regformats/reg-sh.dat $(regdat_sh)
 reg-x86-64.o : reg-x86-64.c $(regdef_h)
 reg-x86-64.c : $(srcdir)/../regformats/reg-x86-64.dat $(regdat_sh)
        sh $(regdat_sh) $(srcdir)/../regformats/reg-x86-64.dat reg-x86-64.c
+reg-x86-64-linux.o : reg-x86-64-linux.c $(regdef_h)
+reg-x86-64-linux.c : $(srcdir)/../regformats/reg-x86-64-linux.dat $(regdat_sh)
+       sh $(regdat_sh) $(srcdir)/../regformats/reg-x86-64-linux.dat reg-x86-64-linux.c
 
 # This is the end of "Makefile.in".
index 46383db58e10d54b37e2df33a8ae5e16e9e05ade..40805e5e536066012acc0e981e98f51c500538a7 100644 (file)
@@ -97,7 +97,7 @@ case "${target}" in
                        srv_linux_usrregs=yes
                        srv_linux_thread_db=yes
                        ;;
-  x86_64-*-linux*)     srv_regobj=reg-x86-64.o
+  x86_64-*-linux*)     srv_regobj=reg-x86-64-linux.o
                        srv_tgtobj="linux-low.o linux-x86-64-low.o i387-fp.o"
                        srv_linux_regsets=yes
                        srv_linux_thread_db=yes
index 43cd10b0b396d4078dae648953741bc0d0d93933..e067b9c5ede7f44aa37c2c0f93f2cde561f52092 100644 (file)
@@ -50,7 +50,12 @@ static int x86_64_regmap[] = {
   R8 * 8, R9 * 8, R10 * 8, R11 * 8,
   R12 * 8, R13 * 8, R14 * 8, R15 * 8,
   RIP * 8, EFLAGS * 8, CS * 8, SS * 8, 
-  DS * 8, ES * 8, FS * 8, GS * 8
+  DS * 8, ES * 8, FS * 8, GS * 8,
+  -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
 };
 
 #define X86_64_NUM_GREGS (sizeof(x86_64_regmap)/sizeof(int))
@@ -83,7 +88,8 @@ x86_64_fill_gregset (void *buf)
   int i;
 
   for (i = 0; i < X86_64_NUM_GREGS; i++)
-    collect_register (i, ((char *) buf) + x86_64_regmap[i]);
+    if (x86_64_regmap[i] != -1)
+      collect_register (i, ((char *) buf) + x86_64_regmap[i]);
 }
 
 static void
@@ -92,7 +98,8 @@ x86_64_store_gregset (const void *buf)
   int i;
 
   for (i = 0; i < X86_64_NUM_GREGS; i++)
-    supply_register (i, ((char *) buf) + x86_64_regmap[i]);
+    if (x86_64_regmap[i] != -1)
+      supply_register (i, ((char *) buf) + x86_64_regmap[i]);
 }
 
 static void
diff --git a/gdb/regformats/reg-x86-64-linux.dat b/gdb/regformats/reg-x86-64-linux.dat
new file mode 100644 (file)
index 0000000..47d324a
--- /dev/null
@@ -0,0 +1,60 @@
+name:x86_64_linux
+expedite:rbp,rsp,rip
+64:rax
+64:rbx
+64:rcx
+64:rdx
+64:rsi
+64:rdi
+64:rbp
+64:rsp
+64:r8
+64:r9
+64:r10
+64:r11
+64:r12
+64:r13
+64:r14
+64:r15
+64:rip
+32:eflags
+32:cs
+32:ss
+32:ds
+32:es
+32:fs
+32:gs
+80:st0
+80:st1
+80:st2
+80:st3
+80:st4
+80:st5
+80:st6
+80:st7
+32:fctrl
+32:fstat
+32:ftag
+32:fiseg
+32:fioff
+32:foseg
+32:fooff
+32:fop
+128:xmm0
+128:xmm1
+128:xmm2
+128:xmm3
+128:xmm4
+128:xmm5
+128:xmm6
+128:xmm7
+128:xmm8
+128:xmm9
+128:xmm10
+128:xmm11
+128:xmm12
+128:xmm13
+128:xmm14
+128:xmm15
+32:mxcsr
+64:orig_rax