Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* Re: [PATCH/i386newframe] amd64newframe
@ 2003-05-17 18:34 Andreas Jaeger
  2003-05-17 22:26 ` Mark Kettenis
  0 siblings, 1 reply; 14+ messages in thread
From: Andreas Jaeger @ 2003-05-17 18:34 UTC (permalink / raw)
  To: Mark M. Kettenis; +Cc: gdb-patches, Michal Ludvig


Mark,

building the kettenis-newframe-branch on x86-64 I get:

make[1]: *** No rule to make target `inux-proc.o', needed by `libgdb.a'.  Stop.
make[1]: Leaving directory `/usr/src/aj/gdb-test/build/gdb'
make: *** [all-gdb] Error 2


Note the following:
./config/i386/x86-64linux.mh:   proc-service.o thread-db.o lin-lwp.o inux-proc.o gcore.o 

After fixing this problem, gdb build fine but running it I got:

byrd:/usr/src/aj/gdb-test/build/gdb:[0]$ ./gdb ~/tmp/a.out 
A handler for the OS ABI "GNU/Linux" is not built into this configuration of GDB.  Attempting to continue with the default i386 settingsGNU gdb 2003-05-04-cvs
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu"...
Setting up the environment for debugging gdb.
.gdbinit:5: Error in sourced command file:
Function "internal_error" not defined.
(gdb) b main
Breakpoint 1 at 0x40040c: file b.c, line 4.
(gdb) r
Starting program: /suse/aj/tmp/a.out 

Breakpoint 1, main () at b.c:4
4       lg1[1] = 1;
(gdb) n
warning: Unmapped DWARF Register #16 encountered

warning: Unmapped DWARF Register #16 encountered

5       lg2[1] = 1;
(gdb) 
warning: Unmapped DWARF Register #16 encountered

6       return 0;
(gdb) 
warning: Unmapped DWARF Register #16 encountered

7       }

And this also:

$ ./gdb /bin/ls 
A handler for the OS ABI "GNU/Linux" is not built into this configuration of GDB.  Attempting to continue with the default i386 settingsGNU gdb 2003-05-04-cvs
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu"...
(no debugging symbols found)...
Setting up the environment for debugging gdb.
.gdbinit:5: Error in sourced command file:
Function "internal_error" not defined.
(gdb) b main
Function "main" not defined.
(gdb) r
Starting program: /bin/ls 
(no debugging symbols found)...[New Thread 16384 (LWP 4561)]

../../src/gdb/arch-utils.c:443: internal-error: generic_register_size: Assertion `regnum >= 0 && regnum < NUM_REGS + NUM_PSEUDO_REGS' failed.
A problem internal to GDB has been detected.  Further
debugging may prove unreliable.

I don't have time to go into details here but hope that Michal can.

Andreas
-- 
 Andreas Jaeger
  SuSE Labs aj@suse.de
   private aj@arthur.inka.de
    http://www.suse.de/~aj


^ permalink raw reply	[flat|nested] 14+ messages in thread
* [PATCH/i386newframe] amd64newframe
@ 2003-05-17 15:19 Mark Kettenis
  2003-05-19 15:31 ` Elena Zannoni
  0 siblings, 1 reply; 14+ messages in thread
From: Mark Kettenis @ 2003-05-17 15:19 UTC (permalink / raw)
  To: gdb-patches, mludvig; +Cc: aj

Folks,

I've checked in on my i386newframe branch a major overhaul of the
x86-64 (sub)target to make it fit into the new frame unwindig
framework.  I've tried very hard to reduce the gratuitous differences
between the i386 and x86_64 stuff, and cleaned things up quite a bit.
However, this code is *untested*.  The code compiles, that is, I can
build a x86_64-linux cross-debugger on my i386-unknown-freebsd4.7
system (actually I can't since the final link fails because of a
problem with the way we do our shared library support).  It would be
great if someone could provide me with access to an amd64 system.  If
it's running *BSD, I can probably add the necessary support for it to
GDB.  Otherwise I'd appreciate it if someone could test this code on
x86_64-linux.

Mark


Index: ChangeLog
from  Mark Kettenis  <kettenis@gnu.org>
 
	Revise the x86_64 (sub)taget.
	* x86-64-tdep.c, x86-64-linux-tdep.c, x86-64-linux-nat.c,
	config/i386/tm-x86-64linux.h, config/i386/nm-x86-64linux.h,
	config/i386/x86-64-linux.mt, config/i386/x86-64linux.mh: Extensive
	changes.

 
Index: x86-64-linux-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/x86-64-linux-nat.c,v
retrieving revision 1.21
diff -u -p -r1.21 x86-64-linux-nat.c
--- x86-64-linux-nat.c 11 Feb 2003 23:09:59 -0000 1.21
+++ x86-64-linux-nat.c 17 May 2003 14:58:42 -0000
@@ -25,20 +25,30 @@
 #include "inferior.h"
 #include "gdbcore.h"
 #include "regcache.h"
+
 #include "gdb_assert.h"
 #include "gdb_string.h"
-#include "x86-64-tdep.h"
-
 #include <sys/ptrace.h>
 #include <sys/debugreg.h>
 #include <sys/syscall.h>
 #include <sys/procfs.h>
 #include <sys/reg.h>
 
+/* Prototypes for supply_gregset etc.  */
+#include "gregset.h"
+
+#include "x86-64-tdep.h"
+
+/* The register sets used in GNU/Linux ELF core-dumps are identical to
+   the register sets used by `ptrace'.  The corresponding types are
+   `elf_gregset_t' for the general-purpose registers (with
+   `elf_greg_t' the type of a single GP register) and `elf_fpregset_t'
+   for the floating-point registers.
+
 /* Mapping between the general-purpose registers in `struct user'
    format and GDB's register array layout.  */
-
-static int x86_64_regmap[] = {
+static int regmap[] =
+{
   RAX, RBX, RCX, RDX,
   RSI, RDI, RBP, RSP,
   R8, R9, R10, R11,
@@ -47,85 +57,12 @@ static int x86_64_regmap[] = {
   DS, ES, FS, GS
 };
 
-static unsigned long
-x86_64_linux_dr_get (int regnum)
-{
-  int tid;
-  unsigned long value;
-
-  /* FIXME: kettenis/2001-01-29: It's not clear what we should do with
-     multi-threaded processes here.  For now, pretend there is just
-     one thread.  */
-  tid = PIDGET (inferior_ptid);
-
-  /* FIXME: kettenis/2001-03-27: Calling perror_with_name if the
-     ptrace call fails breaks debugging remote targets.  The correct
-     way to fix this is to add the hardware breakpoint and watchpoint
-     stuff to the target vectore.  For now, just return zero if the
-     ptrace call fails.  */
-  errno = 0;
-  value = ptrace (PT_READ_U, tid,
-		  offsetof (struct user, u_debugreg[regnum]), 0);
-  if (errno != 0)
-#if 0
-    perror_with_name ("Couldn't read debug register");
-#else
-    return 0;
-#endif
-
-  return value;
-}
-
-static void
-x86_64_linux_dr_set (int regnum, unsigned long value)
-{
-  int tid;
-
-  /* FIXME: kettenis/2001-01-29: It's not clear what we should do with
-     multi-threaded processes here.  For now, pretend there is just
-     one thread.  */
-  tid = PIDGET (inferior_ptid);
-
-  errno = 0;
-  ptrace (PT_WRITE_U, tid, offsetof (struct user, u_debugreg[regnum]), value);
-  if (errno != 0)
-    perror_with_name ("Couldn't write debug register");
-}
-
-void
-x86_64_linux_dr_set_control (unsigned long control)
-{
-  x86_64_linux_dr_set (DR_CONTROL, control);
-}
-
-void
-x86_64_linux_dr_set_addr (int regnum, CORE_ADDR addr)
-{
-  gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
-
-  x86_64_linux_dr_set (DR_FIRSTADDR + regnum, addr);
-}
-
-void
-x86_64_linux_dr_reset_addr (int regnum)
-{
-  gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
-
-  x86_64_linux_dr_set (DR_FIRSTADDR + regnum, 0L);
-}
-
-unsigned long
-x86_64_linux_dr_get_status (void)
-{
-  return x86_64_linux_dr_get (DR_STATUS);
-}
-\f
-
-/* The register sets used in GNU/Linux ELF core-dumps are identical to
-   the register sets used by `ptrace'.  */
+/* Which ptrace request retrieves which registers?
+   These apply to the corresponding SET requests as well.  */
 
 #define GETREGS_SUPPLIES(regno) \
-  (0 <= (regno) && (regno) < x86_64_num_gregs)
+  (0 <= (regno) && (regno) < X86_64_NUM_GREGS)
+
 #define GETFPREGS_SUPPLIES(regno) \
   (FP0_REGNUM <= (regno) && (regno) <= MXCSR_REGNUM)
 \f
@@ -137,13 +74,13 @@ x86_64_linux_dr_get_status (void)
    in *GREGSETP.  */
 
 void
-supply_gregset (elf_gregset_t * gregsetp)
+supply_gregset (elf_gregset_t *gregsetp)
 {
   elf_greg_t *regp = (elf_greg_t *) gregsetp;
   int i;
 
-  for (i = 0; i < x86_64_num_gregs; i++)
-    supply_register (i, (char *) (regp + x86_64_regmap[i]));
+  for (i = 0; i < X86_64_NUM_GREGS; i++)
+    supply_register (i, regp + regmap[i]);
 }
 
 /* Fill register REGNO (if it is a general-purpose register) in
@@ -151,14 +88,14 @@ supply_gregset (elf_gregset_t * gregsetp
    do this for all registers.  */
 
 void
-fill_gregset (elf_gregset_t * gregsetp, int regno)
+fill_gregset (elf_gregset_t *gregsetp, int regno)
 {
   elf_greg_t *regp = (elf_greg_t *) gregsetp;
   int i;
 
-  for (i = 0; i < x86_64_num_gregs; i++)
-    if ((regno == -1 || regno == i))
-      regcache_collect (i, (char *) (regp + x86_64_regmap[i]));
+  for (i = 0; i < X86_64_NUM_GREGS; i++)
+    if (regno == -1 || regno == i)
+      regcache_collect (i, regp + regmap[i]);
 }
 
 /* Fetch all general-purpose registers from process/thread TID and
@@ -195,73 +132,23 @@ store_regs (int tid, int regno)
 
 /* Transfering floating-point registers between GDB, inferiors and cores.  */
 
-static void *
-x86_64_fxsave_offset (elf_fpregset_t * fxsave, int regnum)
-{
-  const char *reg_name;
-  int reg_index;
-
-  gdb_assert (x86_64_num_gregs - 1 < regnum && regnum < x86_64_num_regs);
-
-  reg_name = x86_64_register_name (regnum);
-
-  if (reg_name[0] == 's' && reg_name[1] == 't')
-    {
-      reg_index = reg_name[2] - '0';
-      return &fxsave->st_space[reg_index * 2];
-    }
-
-  if (reg_name[0] == 'x' && reg_name[1] == 'm' && reg_name[2] == 'm')
-    {
-      reg_index = reg_name[3] - '0';
-      return &fxsave->xmm_space[reg_index * 4];
-    }
-
-  if (strcmp (reg_name, "mxcsr") == 0)
-    return &fxsave->mxcsr;
-
-  return NULL;
-}
-
 /* Fill GDB's register array with the floating-point and SSE register
-   values in *FXSAVE.  This function masks off any of the reserved
-   bits in *FXSAVE.  */
+   values in *FPREGSETP.  */
 
 void
-supply_fpregset (elf_fpregset_t * fxsave)
+supply_fpregset (elf_fpregset_t *fpregsetp)
 {
-  int i, reg_st0, reg_mxcsr;
-
-  reg_st0 = x86_64_register_number ("st0");
-  reg_mxcsr = x86_64_register_number ("mxcsr");
-
-  gdb_assert (reg_st0 > 0 && reg_mxcsr > reg_st0);
-
-  for (i = reg_st0; i <= reg_mxcsr; i++)
-    supply_register (i, x86_64_fxsave_offset (fxsave, i));
+  x86_64_supply_fxsave ((char *) fpregsetp);
 }
 
 /* Fill register REGNUM (if it is a floating-point or SSE register) in
-   *FXSAVE with the value in GDB's register array.  If REGNUM is -1, do
-   this for all registers.  This function doesn't touch any of the
-   reserved bits in *FXSAVE.  */
+   *FPREGSETP with the value in GDB's register array.  If REGNUM is
+   -1, do this for all registers.  */
 
 void
-fill_fpregset (elf_fpregset_t * fxsave, int regnum)
+fill_fpregset (elf_fpregset_t *fpregsetp, int regnum)
 {
-  int i, last_regnum = MXCSR_REGNUM;
-  void *ptr;
-
-  if (gdbarch_tdep (current_gdbarch)->num_xmm_regs == 0)
-    last_regnum = FOP_REGNUM;
-
-  for (i = FP0_REGNUM; i <= last_regnum; i++)
-    if (regnum == -1 || regnum == i)
-      {
-	ptr = x86_64_fxsave_offset (fxsave, i);
-	if (ptr)
-	  regcache_collect (i, ptr);
-      }
+  x86_64_fill_fxsave ((char *) fpregsetp, regnum);
 }
 
 /* Fetch all floating-point registers from process/thread TID and store
@@ -308,8 +195,9 @@ fetch_inferior_registers (int regno)
   int tid;
 
   /* GNU/Linux LWP ID's are process ID's.  */
-  if ((tid = TIDGET (inferior_ptid)) == 0)
-    tid = PIDGET (inferior_ptid);	/* Not a threaded program.  */
+  tid = TIDGET (inferior_ptid);
+  if (tid == 0)
+    tid = PIDGET (inferior_ptid); /* Not a threaded program.  */
 
   if (regno == -1)
     {
@@ -335,16 +223,18 @@ fetch_inferior_registers (int regno)
 }
 
 /* Store register REGNO back into the child process.  If REGNO is -1,
-   do this for all registers (including the floating point and SSE
+   do this for all registers (including the floating-point and SSE
    registers).  */
+
 void
 store_inferior_registers (int regno)
 {
   int tid;
 
   /* GNU/Linux LWP ID's are process ID's.  */
-  if ((tid = TIDGET (inferior_ptid)) == 0)
-    tid = PIDGET (inferior_ptid);	/* Not a threaded program.  */
+  tid = TIDGET (inferior_ptid);
+  if (tid == 0)
+    tid = PIDGET (inferior_ptid); /* Not a threaded program.  */
 
   if (regno == -1)
     {
@@ -370,123 +260,75 @@ store_inferior_registers (int regno)
 }
 \f
 
-static const unsigned char linux_syscall[] = { 0x0f, 0x05 };
-
-#define LINUX_SYSCALL_LEN (sizeof linux_syscall)
-
-/* The system call number is stored in the %rax register.  */
-#define LINUX_SYSCALL_REGNUM 0	/* %rax */
+static unsigned long
+x86_64_linux_dr_get (int regnum)
+{
+  int tid;
+  unsigned long value;
 
-/* We are specifically interested in the sigreturn and rt_sigreturn
-   system calls.  */
+  /* FIXME: kettenis/2001-01-29: It's not clear what we should do with
+     multi-threaded processes here.  For now, pretend there is just
+     one thread.  */
+  tid = PIDGET (inferior_ptid);
 
-#ifndef SYS_sigreturn
-#define SYS_sigreturn		__NR_sigreturn
-#endif
-#ifndef SYS_rt_sigreturn
-#define SYS_rt_sigreturn	__NR_rt_sigreturn
+  /* FIXME: kettenis/2001-03-27: Calling perror_with_name if the
+     ptrace call fails breaks debugging remote targets.  The correct
+     way to fix this is to add the hardware breakpoint and watchpoint
+     stuff to the target vectore.  For now, just return zero if the
+     ptrace call fails.  */
+  errno = 0;
+  value = ptrace (PT_READ_U, tid,
+		  offsetof (struct user, u_debugreg[regnum]), 0);
+  if (errno != 0)
+#if 0
+    perror_with_name ("Couldn't read debug register");
+#else
+    return 0;
 #endif
 
-/* Offset to saved processor flags, from <asm/sigcontext.h>.  */
-#define LINUX_SIGCONTEXT_EFLAGS_OFFSET (152)
-/* Offset to saved processor registers from <asm/ucontext.h> */
-#define LINUX_UCONTEXT_SIGCONTEXT_OFFSET (36)
-
-/* Interpreting register set info found in core files.  */
-/* Provide registers to GDB from a core file.
-
-   CORE_REG_SECT points to an array of bytes, which are the contents
-   of a `note' from a core file which BFD thinks might contain
-   register contents.  CORE_REG_SIZE is its size.
-
-   WHICH says which register set corelow suspects this is:
-     0 --- the general-purpose register set, in elf_gregset_t format
-     2 --- the floating-point register set, in elf_fpregset_t format
-
-   REG_ADDR isn't used on GNU/Linux.  */
+  return value;
+}
 
 static void
-fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
-		      int which, CORE_ADDR reg_addr)
+x86_64_linux_dr_set (int regnum, unsigned long value)
 {
-  elf_gregset_t gregset;
-  elf_fpregset_t fpregset;
-  switch (which)
-    {
-    case 0:
-      if (core_reg_size != sizeof (gregset))
-	warning ("Wrong size gregset in core file.");
-      else
-	{
-	  memcpy (&gregset, core_reg_sect, sizeof (gregset));
-	  supply_gregset (&gregset);
-	}
-      break;
-
-    case 2:
-      if (core_reg_size != sizeof (fpregset))
-	warning ("Wrong size fpregset in core file.");
-      else
-	{
-	  memcpy (&fpregset, core_reg_sect, sizeof (fpregset));
-	  supply_fpregset (&fpregset);
-	}
-      break;
-
-    default:
-      /* We've covered all the kinds of registers we know about here,
-         so this must be something we wouldn't know what to do with
-         anyway.  Just ignore it.  */
-      break;
-    }
-}
+  int tid;
 
-/* Register that we are able to handle GNU/Linux ELF core file formats.  */
+  /* FIXME: kettenis/2001-01-29: It's not clear what we should do with
+     multi-threaded processes here.  For now, pretend there is just
+     one thread.  */
+  tid = PIDGET (inferior_ptid);
 
-static struct core_fns linux_elf_core_fns = {
-  bfd_target_elf_flavour,	/* core_flavour */
-  default_check_format,		/* check_format */
-  default_core_sniffer,		/* core_sniffer */
-  fetch_core_registers,		/* core_read_registers */
-  NULL				/* next */
-};
-\f
+  errno = 0;
+  ptrace (PT_WRITE_U, tid, offsetof (struct user, u_debugreg[regnum]), value);
+  if (errno != 0)
+    perror_with_name ("Couldn't write debug register");
+}
 
-#if !defined (offsetof)
-#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
-#endif
+void
+x86_64_linux_dr_set_control (unsigned long control)
+{
+  x86_64_linux_dr_set (DR_CONTROL, control);
+}
 
-/* Return the address of register REGNUM.  BLOCKEND is the value of
-   u.u_ar0, which should point to the registers.  */
-CORE_ADDR
-x86_64_register_u_addr (CORE_ADDR blockend, int regnum)
-{
-  struct user u;
-  CORE_ADDR fpstate;
-  CORE_ADDR ubase;
-  ubase = blockend;
-  if (IS_FP_REGNUM (regnum))
-    {
-      fpstate = ubase + ((char *) &u.i387.st_space - (char *) &u);
-      return (fpstate + 16 * (regnum - FP0_REGNUM));
-    }
-  else if (IS_SSE_REGNUM (regnum))
-    {
-      fpstate = ubase + ((char *) &u.i387.xmm_space - (char *) &u);
-      return (fpstate + 16 * (regnum - XMM0_REGNUM));
-    }
-  else
-    return (ubase + 8 * x86_64_regmap[regnum]);
+void
+x86_64_linux_dr_set_addr (int regnum, CORE_ADDR addr)
+{
+  gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
+
+  x86_64_linux_dr_set (DR_FIRSTADDR + regnum, addr);
 }
 
 void
-_initialize_x86_64_linux_nat (void)
+x86_64_linux_dr_reset_addr (int regnum)
 {
-  add_core_fns (&linux_elf_core_fns);
+  gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
+
+  x86_64_linux_dr_set (DR_FIRSTADDR + regnum, 0L);
 }
 
-int
-kernel_u_size (void)
+unsigned long
+x86_64_linux_dr_get_status (void)
 {
-  return (sizeof (struct user));
+  return x86_64_linux_dr_get (DR_STATUS);
 }
Index: x86-64-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/x86-64-linux-tdep.c,v
retrieving revision 1.17
diff -u -p -r1.17 x86-64-linux-tdep.c
--- x86-64-linux-tdep.c 14 Jan 2003 00:49:04 -0000 1.17
+++ x86-64-linux-tdep.c 17 May 2003 14:58:42 -0000
@@ -24,19 +24,21 @@
 #include "defs.h"
 #include "inferior.h"
 #include "gdbcore.h"
-#include "gdb_string.h"
 #include "regcache.h"
-#include "x86-64-tdep.h"
-#include "dwarf2cfi.h"
 #include "osabi.h"
 
-#define LINUX_SIGTRAMP_INSN0 (0x48)	/* mov $NNNNNNNN,%rax */
-#define LINUX_SIGTRAMP_OFFSET0 (0)
-#define LINUX_SIGTRAMP_INSN1 (0x0f)	/* syscall */
-#define LINUX_SIGTRAMP_OFFSET1 (7)
+#include "gdb_string.h"
 
-static const unsigned char linux_sigtramp_code[] = {
-  /*  mov $__NR_rt_sigreturn,%rax */
+#include "x86-64-tdep.h"
+
+#define LINUX_SIGTRAMP_INSN0	0x48	/* mov $NNNNNNNN, %rax */
+#define LINUX_SIGTRAMP_OFFSET0	0
+#define LINUX_SIGTRAMP_INSN1	0x0f	/* syscall */
+#define LINUX_SIGTRAMP_OFFSET1	7
+
+static const unsigned char linux_sigtramp_code[] =
+{
+  /* mov $__NR_rt_sigreturn, %rax */
   LINUX_SIGTRAMP_INSN0, 0xc7, 0xc0, 0x0f, 0x00, 0x00, 0x00,
   /* syscall */
   LINUX_SIGTRAMP_INSN1, 0x05
@@ -51,6 +53,14 @@ static CORE_ADDR
 x86_64_linux_sigtramp_start (CORE_ADDR pc)
 {
   unsigned char buf[LINUX_SIGTRAMP_LEN];
+
+  /* We only recognize a signal trampoline if PC is at the start of
+     one of the two instructions.  We optimize for finding the PC at
+     the start, as will be the case when the trampoline is not the
+     first frame on the stack.  We assume that in the case where the
+     PC is not at the start of the instruction sequence, there will be
+     a few trailing readable bytes on the stack.  */
+
   if (read_memory_nobpt (pc, (char *) buf, LINUX_SIGTRAMP_LEN) != 0)
     return 0;
 
@@ -71,133 +81,60 @@ x86_64_linux_sigtramp_start (CORE_ADDR p
   return pc;
 }
 
-#define LINUX_SIGINFO_SIZE 0
-
-/* Offset to struct sigcontext in ucontext, from <asm/ucontext.h>.  */
-#define LINUX_UCONTEXT_SIGCONTEXT_OFFSET 40
-
-/* Offset to saved PC in sigcontext, from <asm/sigcontext.h>.  */
-#define LINUX_SIGCONTEXT_PC_OFFSET 128
-#define LINUX_SIGCONTEXT_FP_OFFSET 120
-
-/* Assuming FRAME is for a GNU/Linux sigtramp routine, return the
-   address of the associated sigcontext structure.  */
-static CORE_ADDR
-x86_64_linux_sigcontext_addr (struct frame_info *frame)
-{
-  CORE_ADDR pc;
-  ULONGEST rsp;
-
-  pc = x86_64_linux_sigtramp_start (get_frame_pc (frame));
-  if (pc)
-    {
-      if (get_next_frame (frame))
-	/* If this isn't the top frame, the next frame must be for the
-	   signal handler itself.  The sigcontext structure is part of
-	   the user context. */
-	return get_frame_base (get_next_frame (frame)) + LINUX_SIGINFO_SIZE +
-	  LINUX_UCONTEXT_SIGCONTEXT_OFFSET;
-
-
-      /* This is the top frame. */
-      rsp = read_register (SP_REGNUM);
-      return rsp + LINUX_SIGINFO_SIZE + LINUX_UCONTEXT_SIGCONTEXT_OFFSET;
-
-    }
-
-  error ("Couldn't recognize signal trampoline.");
-  return 0;
-}
-
-/* Assuming FRAME is for a GNU/Linux sigtramp routine, return the
-   saved program counter.  */
-
-static CORE_ADDR
-x86_64_linux_sigtramp_saved_pc (struct frame_info *frame)
-{
-  CORE_ADDR addr;
-
-  addr = x86_64_linux_sigcontext_addr (frame);
-  return read_memory_integer (addr + LINUX_SIGCONTEXT_PC_OFFSET, 8);
-}
-
-/* Immediately after a function call, return the saved pc.  */
-
-CORE_ADDR
-x86_64_linux_saved_pc_after_call (struct frame_info *frame)
-{
-  if ((get_frame_type (frame) == SIGTRAMP_FRAME))
-    return x86_64_linux_sigtramp_saved_pc (frame);
-
-  return read_memory_integer (read_register (SP_REGNUM), 8);
-}
-
-/* Saved Pc.  Get it from sigcontext if within sigtramp.  */
-CORE_ADDR
-x86_64_linux_frame_saved_pc (struct frame_info *frame)
-{
-  if ((get_frame_type (frame) == SIGTRAMP_FRAME))
-    return x86_64_linux_sigtramp_saved_pc (frame);
-  return cfi_get_ra (frame);
-}
-
 /* Return whether PC is in a GNU/Linux sigtramp routine.  */
 
-int
-x86_64_linux_in_sigtramp (CORE_ADDR pc, char *name)
+static int
+x86_64_linux_pc_in_sigtramp (CORE_ADDR pc, char *name)
 {
-  if (name)
-    return strcmp ("__restore_rt", name) == 0;
+  /* If we have NAME, we can optimize the search.  The trampoline is
+     named __restore_rt.  However, it isn't dynamically exported from
+     the shared C library, so the trampoline may appear to be part of
+     the preceding function.  This should always be sigaction,
+     __sigaction, or __libc_sigaction (all aliases to the same
+     function).  */
+  if (name == NULL || strstr (name, "sigaction") != NULL)
+    return (x86_64_linux_sigtramp_start (pc) != 0);
 
-  return (x86_64_linux_sigtramp_start (pc) != 0);
+  return (strcmp ("__restore_rt", name) == 0);
 }
 
-CORE_ADDR
-x86_64_linux_frame_chain (struct frame_info *fi)
-{
-  ULONGEST addr;
-  CORE_ADDR fp, pc;
-
-  if (!(get_frame_type (fi) == SIGTRAMP_FRAME))
-    {
-      fp = cfi_frame_chain (fi);
-      if (fp)
-	return fp;
-      else
-	addr = get_frame_base (fi);
-    }
-  else
-    addr = get_frame_base (get_next_frame (fi));
-
-  addr += LINUX_SIGINFO_SIZE + LINUX_UCONTEXT_SIGCONTEXT_OFFSET;
-
-  fp = read_memory_integer (addr + LINUX_SIGCONTEXT_FP_OFFSET, 8) + 8;
+/* Offset to struct sigcontext in ucontext, from <asm/ucontext.h>.  */
+#define X86_64_LINUX_UCONTEXT_SIGCONTEXT_OFFSET 40
 
-  return fp;
-}
+/* Assuming NEXT_FRAME is a frame following a GNU/Linux sigtramp
+   routine, return the address of the associated sigcontext structure.  */
 
-CORE_ADDR
-x86_64_init_frame_pc (int fromleaf, struct frame_info *fi)
+static CORE_ADDR
+x86_64_linux_sigcontext_addr (struct frame_info *next_frame)
 {
-  CORE_ADDR addr;
+  CORE_ADDR sp, ucontext_addr;
+  char buf[8];
 
-  if (get_next_frame (fi)
-      && (get_frame_type (get_next_frame (fi)) == SIGTRAMP_FRAME))
-    {
-      addr = get_frame_base (get_next_frame (get_next_frame (fi)))
-	+ LINUX_SIGINFO_SIZE + LINUX_UCONTEXT_SIGCONTEXT_OFFSET;
-      return read_memory_integer (addr + LINUX_SIGCONTEXT_PC_OFFSET, 8);
-    }
-  else
-    return cfi_init_frame_pc (fromleaf, fi);
+  frame_unwind_register (next_frame, SP_REGNUM, buf);
+  sp = extract_unsigned_integer (buf, 8);
+
+  /* The sigcontext structure is part of the user context.  A pointer
+     to the user context is passed as the third argument to the signal
+     handler.  */
+  read_memory (sp + 16, buf, 8);
+  ucontext_addr = extract_unsigned_integer (buf, 8);
+  return ucontext_addr + X86_64_LINUX_UCONTEXT_SIGCONTEXT_OFFSET;
 }
 \f
 
 static void
 x86_64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   x86_64_init_abi (info, gdbarch);
+
+  set_gdbarch_pc_in_sigtramp (gdbarch, x86_64_linux_pc_in_sigtramp);
+
+  tdep->sigcontext_addr = x86_64_linux_sigcontext_addr;
+  tdep->sc_pc_offset = 16 * 8;	/* From <asm/sigcontext.h>.  */
+  tdep->sc_sp_offset = 15 * 8;
 }
+\f
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
 extern void _initialize_x86_64_linux_tdep (void);
Index: x86-64-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/x86-64-tdep.c,v
retrieving revision 1.67.2.1
diff -u -p -r1.67.2.1 x86-64-tdep.c
--- x86-64-tdep.c 4 May 2003 11:37:46 -0000 1.67.2.1
+++ x86-64-tdep.c 17 May 2003 14:58:43 -0000
@@ -21,249 +21,202 @@
    Boston, MA 02111-1307, USA.  */
 
 #include "defs.h"
+#include "arch-utils.h"
+#include "block.h"
+#include "dummy-frame.h"
+#include "dwarf-frame.h"
+#include "frame.h"
+#include "frame-base.h"
+#include "frame-unwind.h"
 #include "inferior.h"
-#include "gdbcore.h"
 #include "gdbcmd.h"
-#include "arch-utils.h"
+#include "gdbcore.h"
+#include "objfiles.h"
 #include "regcache.h"
 #include "symfile.h"
-#include "objfiles.h"
-#include "x86-64-tdep.h"
-#include "dwarf2cfi.h"
+
 #include "gdb_assert.h"
-#include "block.h"
+
+#include "x86-64-tdep.h"
+#include "i387-tdep.h"
 
 /* Register numbers of various important registers.  */
-#define RAX_REGNUM 0
-#define RDX_REGNUM 3
-#define RDI_REGNUM 5
-#define EFLAGS_REGNUM 17
-#define ST0_REGNUM 22
-#define XMM1_REGNUM  39
 
-struct register_info
+#define X86_64_RAX_REGNUM	0 /* %rax */
+#define X86_64_RDX_REGNUM	3 /* %rdx */
+#define X86_64_RDI_REGNUM	5 /* %rdi */
+#define X86_64_RBP_REGNUM	6 /* %rbp */
+#define X86_64_RSP_REGNUM	7 /* %rsp */
+#define X86_64_RIP_REGNUM	16 /* %rip */
+#define X86_64_EFLAGS_REGNUM	17 /* %eflags */
+#define X86_64_ST0_REGNUM	22 /* %st0 */
+#define X86_64_XMM0_REGNUM	38 /* %xmm0 */
+#define X86_64_XMM1_REGNUM	39 /* %xmm1 */
+
+struct x86_64_register_info
 {
-  int size;
   char *name;
   struct type **type;
 };
 
-/* x86_64_register_raw_size_table[i] is the number of bytes of storage in
-   GDB's register array occupied by register i.  */
-static struct register_info x86_64_register_info_table[] = {
-  /*  0 */ {8, "rax", &builtin_type_int64},
-  /*  1 */ {8, "rbx", &builtin_type_int64},
-  /*  2 */ {8, "rcx", &builtin_type_int64},
-  /*  3 */ {8, "rdx", &builtin_type_int64},
-  /*  4 */ {8, "rsi", &builtin_type_int64},
-  /*  5 */ {8, "rdi", &builtin_type_int64},
-  /*  6 */ {8, "rbp", &builtin_type_void_func_ptr},
-  /*  7 */ {8, "rsp", &builtin_type_void_func_ptr},
-  /*  8 */ {8, "r8", &builtin_type_int64},
-  /*  9 */ {8, "r9", &builtin_type_int64},
-  /* 10 */ {8, "r10", &builtin_type_int64},
-  /* 11 */ {8, "r11", &builtin_type_int64},
-  /* 12 */ {8, "r12", &builtin_type_int64},
-  /* 13 */ {8, "r13", &builtin_type_int64},
-  /* 14 */ {8, "r14", &builtin_type_int64},
-  /* 15 */ {8, "r15", &builtin_type_int64},
-  /* 16 */ {8, "rip", &builtin_type_void_func_ptr},
-  /* 17 */ {4, "eflags", &builtin_type_int32},
-  /* 18 */ {4, "ds", &builtin_type_int32},
-  /* 19 */ {4, "es", &builtin_type_int32},
-  /* 20 */ {4, "fs", &builtin_type_int32},
-  /* 21 */ {4, "gs", &builtin_type_int32},
-  /* 22 */ {10, "st0", &builtin_type_i387_ext},
-  /* 23 */ {10, "st1", &builtin_type_i387_ext},
-  /* 24 */ {10, "st2", &builtin_type_i387_ext},
-  /* 25 */ {10, "st3", &builtin_type_i387_ext},
-  /* 26 */ {10, "st4", &builtin_type_i387_ext},
-  /* 27 */ {10, "st5", &builtin_type_i387_ext},
-  /* 28 */ {10, "st6", &builtin_type_i387_ext},
-  /* 29 */ {10, "st7", &builtin_type_i387_ext},
-  /* 30 */ {4, "fctrl", &builtin_type_int32},
-  /* 31 */ {4, "fstat", &builtin_type_int32},
-  /* 32 */ {4, "ftag", &builtin_type_int32},
-  /* 33 */ {4, "fiseg", &builtin_type_int32},
-  /* 34 */ {4, "fioff", &builtin_type_int32},
-  /* 35 */ {4, "foseg", &builtin_type_int32},
-  /* 36 */ {4, "fooff", &builtin_type_int32},
-  /* 37 */ {4, "fop", &builtin_type_int32},
-  /* 38 */ {16, "xmm0", &builtin_type_v4sf},
-  /* 39 */ {16, "xmm1", &builtin_type_v4sf},
-  /* 40 */ {16, "xmm2", &builtin_type_v4sf},
-  /* 41 */ {16, "xmm3", &builtin_type_v4sf},
-  /* 42 */ {16, "xmm4", &builtin_type_v4sf},
-  /* 43 */ {16, "xmm5", &builtin_type_v4sf},
-  /* 44 */ {16, "xmm6", &builtin_type_v4sf},
-  /* 45 */ {16, "xmm7", &builtin_type_v4sf},
-  /* 46 */ {16, "xmm8", &builtin_type_v4sf},
-  /* 47 */ {16, "xmm9", &builtin_type_v4sf},
-  /* 48 */ {16, "xmm10", &builtin_type_v4sf},
-  /* 49 */ {16, "xmm11", &builtin_type_v4sf},
-  /* 50 */ {16, "xmm12", &builtin_type_v4sf},
-  /* 51 */ {16, "xmm13", &builtin_type_v4sf},
-  /* 52 */ {16, "xmm14", &builtin_type_v4sf},
-  /* 53 */ {16, "xmm15", &builtin_type_v4sf},
-  /* 54 */ {4, "mxcsr", &builtin_type_int32}
-};
-
-/* This array is a mapping from Dwarf-2 register 
-   numbering to GDB's one. Dwarf-2 numbering is 
-   defined in x86-64 ABI, section 3.6.  */
-static int x86_64_dwarf2gdb_regno_map[] = {
-  0, 1, 2, 3,			/* RAX - RDX */
-  4, 5, 6, 7,			/* RSI, RDI, RBP, RSP */
-  8, 9, 10, 11,			/* R8 - R11 */
-  12, 13, 14, 15,		/* R12 - R15 */
-  -1,				/* RA - not mapped */
-  XMM1_REGNUM - 1, XMM1_REGNUM,	/* XMM0 ... */
-  XMM1_REGNUM + 1, XMM1_REGNUM + 2,
-  XMM1_REGNUM + 3, XMM1_REGNUM + 4,
-  XMM1_REGNUM + 5, XMM1_REGNUM + 6,
-  XMM1_REGNUM + 7, XMM1_REGNUM + 8,
-  XMM1_REGNUM + 9, XMM1_REGNUM + 10,
-  XMM1_REGNUM + 11, XMM1_REGNUM + 12,
-  XMM1_REGNUM + 13, XMM1_REGNUM + 14,	/* ... XMM15 */
-  ST0_REGNUM + 0, ST0_REGNUM + 1,	/* ST0 ... */
-  ST0_REGNUM + 2, ST0_REGNUM + 3,
-  ST0_REGNUM + 4, ST0_REGNUM + 5,
-  ST0_REGNUM + 6, ST0_REGNUM + 7	/* ... ST7 */
+static struct x86_64_register_info x86_64_register_info[] =
+{
+  { "rax", &builtin_type_int64 },
+  { "rbx", &builtin_type_int64 },
+  { "rcx", &builtin_type_int64 },
+  { "rdx", &builtin_type_int64 },
+  { "rsi", &builtin_type_int64 },
+  { "rdi", &builtin_type_int64 },
+  { "rbp", &builtin_type_void_data_ptr },
+  { "rsp", &builtin_type_void_data_ptr },
+
+  /* %r8 is indeed register number 8.  */
+  { "r8", &builtin_type_int64 },
+  { "r9", &builtin_type_int64 },
+  { "r10", &builtin_type_int64 },
+  { "r11", &builtin_type_int64 },
+  { "r12", &builtin_type_int64 },
+  { "r13", &builtin_type_int64 },
+  { "r14", &builtin_type_int64 },
+  { "r15", &builtin_type_int64 },
+  { "rip", &builtin_type_void_func_ptr },
+  { "eflags", &builtin_type_int32 },
+  { "ds", &builtin_type_int32 },
+  { "es", &builtin_type_int32 },
+  { "fs", &builtin_type_int32 },
+  { "gs", &builtin_type_int32 },
+
+  /* %st0 is register number 22.  */
+  { "st0", &builtin_type_i387_ext },
+  { "st1", &builtin_type_i387_ext },
+  { "st2", &builtin_type_i387_ext },
+  { "st3", &builtin_type_i387_ext },
+  { "st4", &builtin_type_i387_ext },
+  { "st5", &builtin_type_i387_ext },
+  { "st6", &builtin_type_i387_ext },
+  { "st7", &builtin_type_i387_ext },
+  { "fctrl", &builtin_type_int32 },
+  { "fstat", &builtin_type_int32 },
+  { "ftag", &builtin_type_int32 },
+  { "fiseg", &builtin_type_int32 },
+  { "fioff", &builtin_type_int32 },
+  { "foseg", &builtin_type_int32 },
+  { "fooff", &builtin_type_int32 },
+  { "fop", &builtin_type_int32 },
+
+  /* %xmm0 is register number 38.  */
+  { "xmm0", &builtin_type_v4sf },
+  { "xmm1", &builtin_type_v4sf },
+  { "xmm2", &builtin_type_v4sf },
+  { "xmm3", &builtin_type_v4sf },
+  { "xmm4", &builtin_type_v4sf },
+  { "xmm5", &builtin_type_v4sf },
+  { "xmm6", &builtin_type_v4sf },
+  { "xmm7", &builtin_type_v4sf },
+  { "xmm8", &builtin_type_v4sf },
+  { "xmm9", &builtin_type_v4sf },
+  { "xmm10", &builtin_type_v4sf },
+  { "xmm11", &builtin_type_v4sf },
+  { "xmm12", &builtin_type_v4sf },
+  { "xmm13", &builtin_type_v4sf },
+  { "xmm14", &builtin_type_v4sf },
+  { "xmm15", &builtin_type_v4sf },
+  { "mxcsr", &builtin_type_int32 }
 };
 
-static int x86_64_dwarf2gdb_regno_map_length =
-  sizeof (x86_64_dwarf2gdb_regno_map) /
-  sizeof (x86_64_dwarf2gdb_regno_map[0]);
-
-/* Number of all registers */
-#define X86_64_NUM_REGS (sizeof (x86_64_register_info_table) / \
-  sizeof (x86_64_register_info_table[0]))
+/* Total number of registers.  */
+#define X86_64_NUM_REGS \
+  (sizeof (x86_64_register_info) / sizeof (x86_64_register_info[0]))
 
-/* Number of general registers.  */
-#define X86_64_NUM_GREGS (22)
+/* Size of the register buffer.  */
+static int x86_64_register_bytes;
 
-int x86_64_num_regs = X86_64_NUM_REGS;
-int x86_64_num_gregs = X86_64_NUM_GREGS;
+/* Return the name of register REGNUM.  */
 
-/* Did we already print a note about frame pointer?  */
-int omit_fp_note_printed = 0;
-
-/* Number of bytes of storage in the actual machine representation for
-   register REGNO.  */
-int
-x86_64_register_raw_size (int regno)
+static const char *
+x86_64_register_name (int regnum)
 {
-  return x86_64_register_info_table[regno].size;
-}
+  if (regnum >= 0 && regnum < X86_64_NUM_REGS)
+    return x86_64_register_info[regnum].name;
 
-/* x86_64_register_byte_table[i] is the offset into the register file of the
-   start of register number i.  We initialize this from
-   x86_64_register_info_table.  */
-int x86_64_register_byte_table[X86_64_NUM_REGS];
-
-/* Index within `registers' of the first byte of the space for register REGNO.  */
-int
-x86_64_register_byte (int regno)
-{
-  return x86_64_register_byte_table[regno];
+  return NULL;
 }
 
 /* Return the GDB type object for the "standard" data type of data in
-   register N. */
+   register REGNUM. */
+
 static struct type *
-x86_64_register_virtual_type (int regno)
+x86_64_register_type (struct gdbarch *gdbarch, int regnum)
 {
-  return *x86_64_register_info_table[regno].type;
-}
+  gdb_assert (regnum >= 0 && regnum < X86_64_NUM_REGS);
 
-/* x86_64_register_convertible is true if register N's virtual format is
-   different from its raw format.  Note that this definition assumes
-   that the host supports IEEE 32-bit floats, since it doesn't say
-   that SSE registers need conversion.  Even if we can't find a
-   counterexample, this is still sloppy.  */
-int
-x86_64_register_convertible (int regno)
-{
-  return IS_FP_REGNUM (regno);
+  return *x86_64_register_info[regnum].type;
 }
 
-/* Convert data from raw format for register REGNUM in buffer FROM to
-   virtual format with type TYPE in buffer TO.  In principle both
-   formats are identical except that the virtual format has two extra
-   bytes appended that aren't used.  We set these to zero.  */
-void
-x86_64_register_convert_to_virtual (int regnum, struct type *type,
-				    char *from, char *to)
+/* DWARF Register Number Mapping as defined in the System V psABI,
+   section 3.6.  */
+
+static int x86_64_dwarf_regmap[] =
 {
-  char buf[12];
+  /* General Purpose Registers RAX, RDX, RCX, RBX, RSI, RDI.  */
+  X86_64_RAX_REGNUM, X86_64_RDX_REGNUM, 3, 2, 
+  4, X86_64_RDI_REGNUM,
 
-  /* We only support floating-point values.  */
-  if (TYPE_CODE (type) != TYPE_CODE_FLT)
-    {
-      warning ("Cannot convert floating-point register value "
-	       "to non-floating-point type.");
-      memset (to, 0, TYPE_LENGTH (type));
-      return;
-    }
-  /* First add the necessary padding.  */
-  memcpy (buf, from, FPU_REG_RAW_SIZE);
-  memset (buf + FPU_REG_RAW_SIZE, 0, sizeof buf - FPU_REG_RAW_SIZE);
-  /* Convert to TYPE.  This should be a no-op, if TYPE is equivalent
-     to the extended floating-point format used by the FPU.  */
-  convert_typed_floating (to, type, buf,
-			  x86_64_register_virtual_type (regnum));
-}
+  /* Frame Pointer Register RBP.  */
+  X86_64_RBP_REGNUM,
 
-/* Convert data from virtual format with type TYPE in buffer FROM to
-   raw format for register REGNUM in buffer TO.  Simply omit the two
-   unused bytes.  */
+  /* Stack Pointer Register RSP.  */
+  X86_64_RSP_REGNUM,
 
-void
-x86_64_register_convert_to_raw (struct type *type, int regnum,
-				char *from, char *to)
-{
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) == 12);
-  /* Simply omit the two unused bytes.  */
-  memcpy (to, from, FPU_REG_RAW_SIZE);
-}
+  /* Extended Integer Registers 8 - 15.  */
+  8, 9, 10, 11, 12, 13, 14, 15,
 
-/* Dwarf-2 <-> GDB register numbers mapping.  */
-int
-x86_64_dwarf2_reg_to_regnum (int dw_reg)
-{
-  if (dw_reg < 0 || dw_reg > x86_64_dwarf2gdb_regno_map_length)
-    {
-      warning ("Dwarf-2 uses unmapped register #%d\n", dw_reg);
-      return dw_reg;
-    }
+  /* Return Address RA.  Not mapped.  */
+  -1,
 
-  return x86_64_dwarf2gdb_regno_map[dw_reg];
-}
+  /* SSE Registers 0 - 7.  */
+  X86_64_XMM0_REGNUM + 0, X86_64_XMM1_REGNUM,
+  X86_64_XMM0_REGNUM + 2, X86_64_XMM0_REGNUM + 3,
+  X86_64_XMM0_REGNUM + 4, X86_64_XMM0_REGNUM + 5,
+  X86_64_XMM0_REGNUM + 6, X86_64_XMM0_REGNUM + 7,
 
-/* Push the return address (pointing to the call dummy) onto the stack
-   and return the new value for the stack pointer.  */
+  /* Extended SSE Registers 8 - 15.  */
+  X86_64_XMM0_REGNUM + 8, X86_64_XMM0_REGNUM + 9,
+  X86_64_XMM0_REGNUM + 10, X86_64_XMM0_REGNUM + 11,
+  X86_64_XMM0_REGNUM + 12, X86_64_XMM0_REGNUM + 13,
+  X86_64_XMM0_REGNUM + 14, X86_64_XMM0_REGNUM + 15,
 
-static CORE_ADDR
-x86_64_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
-{
-  char buf[8];
+  /* Floating Point Registers 0-7.  */
+  X86_64_ST0_REGNUM + 0, X86_64_ST0_REGNUM + 1,	
+  X86_64_ST0_REGNUM + 2, X86_64_ST0_REGNUM + 3,
+  X86_64_ST0_REGNUM + 4, X86_64_ST0_REGNUM + 5,
+  X86_64_ST0_REGNUM + 6, X86_64_ST0_REGNUM + 7
+};
 
-  store_unsigned_integer (buf, 8, CALL_DUMMY_ADDRESS ());
-  write_memory (sp - 8, buf, 8);
-  return sp - 8;
-}
+static const int x86_64_dwarf_regmap_len =
+  (sizeof (x86_64_dwarf_regmap) / sizeof (x86_64_dwarf_regmap[0]));
 
-static void
-x86_64_pop_frame (void)
+/* Convert DWARF register number REG to the appropriate register
+   number used by GDB.  */
+
+static int
+x86_64_dwarf_reg_to_regnum (int reg)
 {
-  generic_pop_current_frame (cfi_pop_frame);
+  int regnum = -1;
+
+  if (reg >= 0 || reg < x86_64_dwarf_regmap_len)
+    regnum = x86_64_dwarf_regmap[reg];
+
+  if (regnum == -1)
+    warning ("Unmapped DWARF Register #%d encountered\n", reg);
+
+  return regnum;
 }
 \f
 
 /* The returning of values is done according to the special algorithm.
-   Some types are returned in registers an some (big structures) in memory.
-   See ABI for details.
- */
+   Some types are returned in registers an some (big structures) in
+   memory.  See the System V psABI for details.  */
 
 #define MAX_CLASSES 4
 
@@ -282,27 +235,27 @@ enum x86_64_reg_class
 };
 
 /* Return the union class of CLASS1 and CLASS2.
-   See the x86-64 ABI for details.  */
+   See the System V psABI for details.  */
 
 static enum x86_64_reg_class
 merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
 {
-  /* Rule #1: If both classes are equal, this is the resulting class.  */
+  /* Rule (a): If both classes are equal, this is the resulting class.  */
   if (class1 == class2)
     return class1;
 
-  /* Rule #2: If one of the classes is NO_CLASS, the resulting class
+  /* Rule (b): If one of the classes is NO_CLASS, the resulting class
      is the other class.  */
   if (class1 == X86_64_NO_CLASS)
     return class2;
   if (class2 == X86_64_NO_CLASS)
     return class1;
 
-  /* Rule #3: If one of the classes is MEMORY, the result is MEMORY.  */
+  /* Rule (c): If one of the classes is MEMORY, the result is MEMORY.  */
   if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
     return X86_64_MEMORY_CLASS;
 
-  /* Rule #4: If one of the classes is INTEGER, the result is INTEGER.  */
+  /* Rule (d): If one of the classes is INTEGER, the result is INTEGER.  */
   if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
       || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
     return X86_64_INTEGERSI_CLASS;
@@ -310,12 +263,13 @@ merge_classes (enum x86_64_reg_class cla
       || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
     return X86_64_INTEGER_CLASS;
 
-  /* Rule #5: If one of the classes is X87 or X87UP class, MEMORY is used.  */
+  /* Rule (e): If one of the classes is X87 or X87UP class, MEMORY is
+     used as class.  */
   if (class1 == X86_64_X87_CLASS || class1 == X86_64_X87UP_CLASS
       || class2 == X86_64_X87_CLASS || class2 == X86_64_X87UP_CLASS)
     return X86_64_MEMORY_CLASS;
 
-  /* Rule #6: Otherwise class SSE is used.  */
+  /* Rule (f): Otherwise class SSE is used.  */
   return X86_64_SSE_CLASS;
 }
 
@@ -325,7 +279,7 @@ merge_classes (enum x86_64_reg_class cla
    is returned.  As a special case for zero sized containers,
    classes[0] will be NO_CLASS and 1 is returned.
 
-   See the x86-64 psABI for details.  */
+   See the System V psABI for details.  */
 
 static int
 classify_argument (struct type *type,
@@ -533,7 +487,8 @@ examine_argument (enum x86_64_reg_class 
    memory. If this function returns 1, GDB will call
    STORE_STRUCT_RETURN and EXTRACT_STRUCT_VALUE_ADDRESS else
    STORE_RETURN_VALUE and EXTRACT_RETURN_VALUE will be used.  */
-int
+
+static int
 x86_64_use_struct_convention (int gcc_p, struct type *value_type)
 {
   enum x86_64_reg_class class[MAX_CLASSES];
@@ -550,7 +505,7 @@ x86_64_use_struct_convention (int gcc_p,
    function return value of TYPE, and copy that, in virtual format,
    into VALBUF.  */
 
-void
+static void
 x86_64_extract_return_value (struct type *type, struct regcache *regcache,
 			     void *valbuf)
 {
@@ -561,15 +516,15 @@ x86_64_extract_return_value (struct type
   int intreg = 0;
   int ssereg = 0;
   int offset = 0;
-  int ret_int_r[RET_INT_REGS] = { RAX_REGNUM, RDX_REGNUM };
-  int ret_sse_r[RET_SSE_REGS] = { XMM0_REGNUM, XMM1_REGNUM };
+  int ret_int_r[RET_INT_REGS] = { X86_64_RAX_REGNUM, X86_64_RDX_REGNUM };
+  int ret_sse_r[RET_SSE_REGS] = { X86_64_XMM0_REGNUM, X86_64_XMM1_REGNUM };
 
   if (!n ||
       !examine_argument (class, n, &needed_intregs, &needed_sseregs) ||
       needed_intregs > RET_INT_REGS || needed_sseregs > RET_SSE_REGS)
     {				/* memory class */
       CORE_ADDR addr;
-      regcache_cooked_read (regcache, RAX_REGNUM, &addr);
+      regcache_cooked_read (regcache, X86_64_RAX_REGNUM, &addr);
       read_memory (addr, valbuf, TYPE_LENGTH (type));
       return;
     }
@@ -610,12 +565,12 @@ x86_64_extract_return_value (struct type
 	      ssereg++;
 	      break;
 	    case X86_64_X87_CLASS:
-	      regcache_cooked_read_part (regcache, FP0_REGNUM,
+	      regcache_cooked_read_part (regcache, X86_64_ST0_REGNUM,
 					 0, 8, (char *) valbuf + offset);
 	      offset += 8;
 	      break;
 	    case X86_64_X87UP_CLASS:
-	      regcache_cooked_read_part (regcache, FP0_REGNUM,
+	      regcache_cooked_read_part (regcache, X86_64_ST0_REGNUM,
 					 8, 2, (char *) valbuf + offset);
 	      offset += 8;
 	      break;
@@ -628,33 +583,29 @@ x86_64_extract_return_value (struct type
     }
 }
 
-static void
-x86_64_frame_init_saved_regs (struct frame_info *fi)
-{
-  /* Do nothing.  Everything is handled by the stack unwinding code.  */
-}
-
 #define INT_REGS 6
-#define SSE_REGS 16
+#define SSE_REGS 8
 
-CORE_ADDR
-x86_64_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
-		       int struct_return, CORE_ADDR struct_addr)
+static CORE_ADDR
+x86_64_push_arguments (struct regcache *regcache, int nargs,
+		       struct value **args, CORE_ADDR sp)
 {
   int intreg = 0;
   int ssereg = 0;
   int i;
-  static int int_parameter_registers[INT_REGS] = {
-    5 /* RDI */ , 4 /* RSI */ ,
-    3 /* RDX */ , 2 /* RCX */ ,
-    8 /* R8  */ , 9		/* R9  */
+  static int int_parameter_registers[INT_REGS] =
+  {
+    X86_64_RDI_REGNUM, 4,	/* %rdi, %rsi */
+    X86_64_RDX_REGNUM, 2,	/* %rdx, %rcx */
+    8, 9			/* %r8, %r9 */
   };
-  /* XMM0 - XMM15  */
-  static int sse_parameter_registers[SSE_REGS] = {
-    XMM1_REGNUM - 1, XMM1_REGNUM, XMM1_REGNUM + 1, XMM1_REGNUM + 2,
-    XMM1_REGNUM + 3, XMM1_REGNUM + 4, XMM1_REGNUM + 5, XMM1_REGNUM + 6,
-    XMM1_REGNUM + 7, XMM1_REGNUM + 8, XMM1_REGNUM + 9, XMM1_REGNUM + 10,
-    XMM1_REGNUM + 11, XMM1_REGNUM + 12, XMM1_REGNUM + 13, XMM1_REGNUM + 14
+  /* %xmm0 - %xmm7 */
+  static int sse_parameter_registers[SSE_REGS] =
+  {
+    X86_64_XMM0_REGNUM + 0, X86_64_XMM1_REGNUM,
+    X86_64_XMM0_REGNUM + 2, X86_64_XMM0_REGNUM + 3,
+    X86_64_XMM0_REGNUM + 4, X86_64_XMM0_REGNUM + 5,
+    X86_64_XMM0_REGNUM + 6, X86_64_XMM0_REGNUM + 7,
   };
   int stack_values_count = 0;
   int *stack_values;
@@ -684,19 +635,18 @@ x86_64_push_arguments (int nargs, struct
 		case X86_64_NO_CLASS:
 		  break;
 		case X86_64_INTEGER_CLASS:
-		  deprecated_write_register_gen (int_parameter_registers
-						 [(intreg + 1) / 2],
-						 VALUE_CONTENTS_ALL (args[i]) + offset);
+		  regcache_cooked_write
+		    (regcache, int_parameter_registers[(intreg + 1) / 2],
+		     VALUE_CONTENTS_ALL (args[i]) + offset);
 		  offset += 8;
 		  intreg += 2;
 		  break;
 		case X86_64_INTEGERSI_CLASS:
 		  {
-		    LONGEST num
-		      = extract_signed_integer (VALUE_CONTENTS_ALL (args[i])
-						+ offset, 4);
-		    regcache_raw_write_signed (current_regcache,
-					       int_parameter_registers[intreg / 2],                                           num);
+		    LONGEST val = extract_signed_integer
+		      (VALUE_CONTENTS_ALL (args[i]) + offset, 4);
+		    regcache_cooked_write_signed
+		      (regcache, int_parameter_registers[intreg / 2], val);
 
 		    offset += 8;
 		    intreg++;
@@ -705,15 +655,16 @@ x86_64_push_arguments (int nargs, struct
 		case X86_64_SSEDF_CLASS:
 		case X86_64_SSESF_CLASS:
 		case X86_64_SSE_CLASS:
-		  deprecated_write_register_gen (sse_parameter_registers
-						 [(ssereg + 1) / 2],
-						 VALUE_CONTENTS_ALL (args[i]) + offset);
+		  regcache_cooked_write
+		    (regcache, sse_parameter_registers[(ssereg + 1) / 2],
+		     VALUE_CONTENTS_ALL (args[i]) + offset);
 		  offset += 8;
 		  ssereg += 2;
 		  break;
 		case X86_64_SSEUP_CLASS:
-		  deprecated_write_register_gen (sse_parameter_registers[ssereg / 2],
-						 VALUE_CONTENTS_ALL (args[i]) + offset);
+		  regcache_cooked_write
+		    (regcache, sse_parameter_registers[ssereg / 2],
+		     VALUE_CONTENTS_ALL (args[i]) + offset);
 		  offset += 8;
 		  ssereg++;
 		  break;
@@ -732,21 +683,25 @@ x86_64_push_arguments (int nargs, struct
 	    }
 	}
     }
+
+  /* Push any remaining arguments onto the stack.  */
   while (--stack_values_count >= 0)
     {
       struct value *arg = args[stack_values[stack_values_count]];
       int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg));
-      len += 7;
-      len -= len % 8;
-      sp -= len;
+
+      /* Make sure the stack stays eightbyte-aligned.  */
+      sp -= (len + 7) & ~7;
       write_memory (sp, VALUE_CONTENTS_ALL (arg), len);
     }
+
   return sp;
 }
 
 /* Write into the appropriate registers a function return value stored
    in VALBUF of type TYPE, given in virtual format.  */
-void
+
+static void
 x86_64_store_return_value (struct type *type, struct regcache *regcache,
 			   const void *valbuf)
 {
@@ -754,27 +709,32 @@ x86_64_store_return_value (struct type *
 
   if (TYPE_CODE_FLT == TYPE_CODE (type))
     {
-      /* Floating-point return values can be found in %st(0).  */
-      if (len == TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT
-	  && TARGET_LONG_DOUBLE_FORMAT == &floatformat_i387_ext)
-	{
-	  /* Copy straight over.  */
-	  regcache_cooked_write (regcache, FP0_REGNUM, valbuf);
-	}
-      else
-	{
-	  char buf[FPU_REG_RAW_SIZE];
-	  DOUBLEST val;
+      ULONGEST fstat;
+      char buf[FPU_REG_RAW_SIZE];
 
-	  /* Convert the value found in VALBUF to the extended
-	     floating point format used by the FPU.  This is probably
-	     not exactly how it would happen on the target itself, but
-	     it is the best we can do.  */
-	  val = deprecated_extract_floating (valbuf, TYPE_LENGTH (type));
-	  floatformat_from_doublest (&floatformat_i387_ext, &val, buf);
-	  regcache_cooked_write_part (regcache, FP0_REGNUM,
-			  	      0, FPU_REG_RAW_SIZE, buf);
-	}
+      /* Returning floating-point values is a bit tricky.  Apart from
+         storing the return value in %st(0), we have to simulate the
+         state of the FPU at function return point.  */
+
+      /* Convert the value found in VALBUF to the extended
+	 floating-point format used by the FPU.  This is probably
+	 not exactly how it would happen on the target itself, but
+	 it is the best we can do.  */
+      convert_typed_floating (valbuf, type, buf, builtin_type_i387_ext);
+      regcache_raw_write (regcache, X86_64_ST0_REGNUM, buf);
+
+      /* Set the top of the floating-point register stack to 7.  The
+         actual value doesn't really matter, but 7 is what a normal
+         function return would end up with if the program started out
+         with a freshly initialized FPU.  */
+      regcache_raw_read_unsigned (regcache, FSTAT_REGNUM, &fstat);
+      fstat |= (7 << 11);
+      regcache_raw_write_unsigned (regcache, FSTAT_REGNUM, fstat);
+
+      /* Mark %st(1) through %st(7) as empty.  Since we set the top of
+         the floating-point register stack to 7, the appropriate value
+         for the tag word is 0x3fff.  */
+      regcache_raw_write_unsigned (regcache, FTAG_REGNUM, 0x3fff);
     }
   else
     {
@@ -797,119 +757,385 @@ x86_64_store_return_value (struct type *
 }
 \f
 
-const char *
-x86_64_register_name (int reg_nr)
+static CORE_ADDR
+x86_64_push_dummy_call (struct gdbarch *gdbarch, struct regcache *regcache,
+			CORE_ADDR dummy_addr, int nargs, struct value **args,
+			CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr)
 {
-  if (reg_nr < 0 || reg_nr >= X86_64_NUM_REGS)
-    return NULL;
-  return x86_64_register_info_table[reg_nr].name;
+  char buf[8];
+
+  /* Pass arguments.  */
+  sp = x86_64_push_arguments (regcache, nargs, args, sp);
+
+  /* Pass "hidden" argument".  */
+  if (struct_return)
+    {
+      store_address (buf, 8, struct_addr);
+      regcache_cooked_write (regcache, X86_64_RDI_REGNUM, buf);
+    }
+
+  /* Store return address.  */
+  sp -= 8;
+  store_address (buf, 8, dummy_addr);
+  write_memory (sp, buf, 8);
+
+  /* Finally, update the stack pointer...  */
+  store_address (buf, 8, sp);
+  regcache_cooked_write (regcache, X86_64_RSP_REGNUM, buf);
+
+  /* ...and fake a frame pointer.  */
+  regcache_cooked_write (regcache, X86_64_RBP_REGNUM, buf);
+
+  return sp;
 }
+\f
 
-int
-x86_64_register_number (const char *name)
+/* The maximum number of saved registers.  This should include %rip.  */
+#define X86_64_NUM_SAVED_REGS	17
+
+struct x86_64_frame_cache
 {
-  int reg_nr;
+  /* Base address.  */
+  CORE_ADDR base;
+  CORE_ADDR sp_offset;
+  CORE_ADDR pc;
+
+  /* Saved registers.  */
+  CORE_ADDR saved_regs[X86_64_NUM_SAVED_REGS];
+  CORE_ADDR saved_sp;
+
+  /* Do we have a frame?  */
+  int frameless_p;
+};
+
+/* Allocate and initialize a frame cache.  */
+
+static struct x86_64_frame_cache *
+x86_64_alloc_frame_cache (void)
+{
+  struct x86_64_frame_cache *cache;
+  int i;
 
-  for (reg_nr = 0; reg_nr < X86_64_NUM_REGS; reg_nr++)
-    if (strcmp (name, x86_64_register_info_table[reg_nr].name) == 0)
-      return reg_nr;
-  return -1;
+  cache = FRAME_OBSTACK_ZALLOC (struct x86_64_frame_cache);
+
+  /* Base address.  */
+  cache->base = 0;
+  cache->sp_offset = -8;
+  cache->pc = 0;
+
+  /* Saved registers.  We initialize these to -1 since zero is a valid
+     offset (that's where %rbp is supposed to be stored).  */
+  for (i = 0; i < X86_64_NUM_SAVED_REGS; i++)
+    cache->saved_regs[i] = -1;
+  cache->saved_sp = 0;
+
+  /* Frameless until proven otherwise.  */
+  cache->frameless_p = 1;
+
+  return cache;
 }
-\f
 
-/* Store the address of the place in which to copy the structure the
-   subroutine will return.  This is called from call_function. */
-void
-x86_64_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+/* Do a limited analysis of the prologue at PC and update CACHE
+   accordingly.  Bail out early if CURRENT_PC is reached.  Return the
+   address where the analysis stopped.
+
+   We will handle only functions beginning with:
+
+      pushq %rbp        0x55
+      movq %rsp, %rbp   0x48 0x89 0xe5
+
+   Any function that doesn't start with this sequence will be assumed
+   to have no prologue and thus no valid frame pointer in %rbp.  */
+
+static CORE_ADDR
+x86_64_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
+			 struct x86_64_frame_cache *cache)
 {
-  write_register (RDI_REGNUM, addr);
+  static unsigned char proto[3] = { 0x48, 0x89, 0xe5 };
+  unsigned char buf[3];
+  unsigned char op;
+
+  if (current_pc <= pc)
+    return current_pc;
+
+  op = read_memory_unsigned_integer (pc, 1);
+
+  if (op == 0x55)		/* pushq %rbp */
+    {
+      /* Take into account that we've executed the `pushq %rbp' that
+         starts this instruction sequence.  */
+      cache->saved_regs[X86_64_RBP_REGNUM] = 0;
+      cache->sp_offset += 8;
+
+      /* If that's all, return now.  */
+      if (current_pc <= pc + 1)
+        return current_pc;
+
+      /* Check for `movq %rsp, %rbp'.  */
+      read_memory (pc + 1, buf, 3);
+      if (memcmp (buf, proto, 3) != 0)
+	return pc + 1;
+
+      /* OK, we actually have a frame.  */
+      cache->frameless_p = 0;
+      return pc + 4;
+    }
+
+  return pc;
 }
 
-int
-x86_64_frameless_function_invocation (struct frame_info *frame)
+/* Return PC of first real instruction.  */
+
+static CORE_ADDR
+x86_64_skip_prologue (CORE_ADDR start_pc)
 {
-  return 0;
+  struct x86_64_frame_cache cache;
+  CORE_ADDR pc;
+
+  pc = x86_64_analyze_prologue (start_pc, 0xffffffffffffffff, &cache);
+  if (cache.frameless_p)
+    return start_pc;
+
+  return pc;
 }
+\f
 
-/* We will handle only functions beginning with:
-   55          pushq %rbp
-   48 89 e5    movq %rsp,%rbp
-   Any function that doesn't start with this sequence
-   will be assumed to have no prologue and thus no valid
-   frame pointer in %rbp.  */
-#define PROLOG_BUFSIZE 4
-int
-x86_64_function_has_prologue (CORE_ADDR pc)
+/* Normal frames.  */
+
+static struct x86_64_frame_cache *
+x86_64_frame_cache (struct frame_info *next_frame, void **this_cache)
 {
+  struct x86_64_frame_cache *cache;
+  char buf[8];
   int i;
-  unsigned char prolog_expect[PROLOG_BUFSIZE] = { 0x55, 0x48, 0x89, 0xe5 },
-    prolog_buf[PROLOG_BUFSIZE];
 
-  read_memory (pc, (char *) prolog_buf, PROLOG_BUFSIZE);
+  if (*this_cache)
+    return *this_cache;
 
-  /* First check, whether pc points to pushq %rbp, movq %rsp,%rbp.  */
-  for (i = 0; i < PROLOG_BUFSIZE; i++)
-    if (prolog_expect[i] != prolog_buf[i])
-      return 0;		/* ... no, it doesn't. Nothing to skip.  */
-  
-  return 1;
+  cache = x86_64_alloc_frame_cache ();
+
+  frame_unwind_register (next_frame, X86_64_RBP_REGNUM, buf);
+  cache->base = extract_unsigned_integer (buf, 8);
+  if (cache->base == 0)
+    return cache;
+
+  /* For normal frames, %rip is stored at 8(%rbp).  */
+  cache->saved_regs[X86_64_RIP_REGNUM] = 8;
+
+  cache->pc = frame_func_unwind (next_frame);
+  if (cache->pc != 0)
+    x86_64_analyze_prologue (cache->pc, frame_pc_unwind (next_frame), cache);
+
+  if (cache->frameless_p)
+    {
+      /* We didn't find a valid frame, which means that CACHE->base
+	 currently holds the frame pointer for our calling frame.  If
+	 we're at the start of a function, or somewhere half-way its
+	 prologue, the function's frame probably hasn't been fully
+	 setup yet.  Try to reconstruct the base address for the stack
+	 frame by looking at the stack pointer.  For truly "frameless"
+	 functions this might work too.  */
+
+      frame_unwind_register (next_frame, X86_64_RSP_REGNUM, buf);
+      cache->base = extract_unsigned_integer (buf, 8) + cache->sp_offset;
+    }
+
+  /* Now that we have the base address for the stack frame we can
+     calculate the value of %rsp in the calling frame.  */
+  cache->saved_sp = cache->base + 16;
+
+  /* Adjust all the saved registers such that they contain addresses
+     instead of offsets.  */
+  for (i = 0; i < X86_64_NUM_SAVED_REGS; i++)
+    if (cache->saved_regs[i] != -1)
+      cache->saved_regs[i] += cache->base;
+
+  return cache;
 }
 
-/* If a function with debugging information and known beginning
-   is detected, we will return pc of the next line in the source 
-   code. With this approach we effectively skip the prolog.  */
+static void
+x86_64_frame_this_id (struct frame_info *next_frame, void **this_cache,
+		      struct frame_id *this_id)
+{
+  struct x86_64_frame_cache *cache =
+    x86_64_frame_cache (next_frame, this_cache);
+
+  /* This marks the outermost frame.  */
+  if (cache->base == 0)
+    return;
 
-CORE_ADDR
-x86_64_skip_prologue (CORE_ADDR pc)
+  /* This is meant to halt the backtrace at "_start".  */
+  if (inside_entry_file (cache->pc))
+    return;
+
+  (*this_id) = frame_id_build (cache->base, cache->pc);
+}
+
+static void
+x86_64_frame_prev_register (struct frame_info *next_frame, void **this_cache,
+			    int regnum, int *optimizedp,
+			    enum lval_type *lvalp, CORE_ADDR *addrp,
+			    int *realnump, void *valuep)
 {
-  int i;
-  struct symtab_and_line v_sal;
-  struct symbol *v_function;
-  CORE_ADDR endaddr;
-
-  if (! x86_64_function_has_prologue (pc))
-    return pc;
-
-  /* OK, we have found the prologue and want PC of the first
-     non-prologue instruction.  */
-  pc += PROLOG_BUFSIZE;
-
-  v_function = find_pc_function (pc);
-  v_sal = find_pc_line (pc, 0);
-
-  /* If pc doesn't point to a function with debuginfo, some of the
-     following may be NULL.  */
-  if (!v_function || !v_function->ginfo.value.block || !v_sal.symtab)
-    return pc;
-
-  endaddr = BLOCK_END (SYMBOL_BLOCK_VALUE (v_function));
-
-  for (i = 0; i < v_sal.symtab->linetable->nitems; i++)
-    if (v_sal.symtab->linetable->item[i].pc >= pc
-	&& v_sal.symtab->linetable->item[i].pc < endaddr)
-      {
-	pc = v_sal.symtab->linetable->item[i].pc;
-	break;
-      }
+  struct x86_64_frame_cache *cache =
+    x86_64_frame_cache (next_frame, this_cache);
 
-  return pc;
+  gdb_assert (regnum >= 0);
+
+  if (regnum == SP_REGNUM && cache->saved_sp)
+    {
+      *optimizedp = 0;
+      *lvalp = not_lval;
+      *addrp = 0;
+      *realnump = -1;
+      if (valuep)
+	{
+	  /* Store the value.  */
+	  store_address (valuep, 8, cache->saved_sp);
+	}
+      return;
+    }
+
+  if (regnum < X86_64_NUM_SAVED_REGS && cache->saved_regs[regnum] != -1)
+    {
+      *optimizedp = 0;
+      *lvalp = lval_memory;
+      *addrp = cache->saved_regs[regnum];
+      *realnump = -1;
+      if (valuep)
+	{
+	  /* Read the value in from memory.  */
+	  read_memory (*addrp, valuep,
+		       register_size (current_gdbarch, regnum));
+	}
+      return;
+    }
+
+  frame_register_unwind (next_frame, regnum,
+			 optimizedp, lvalp, addrp, realnump, valuep);
+}
+
+static const struct frame_unwind x86_64_frame_unwind =
+{
+  NORMAL_FRAME,
+  x86_64_frame_this_id,
+  x86_64_frame_prev_register
+};
+
+static const struct frame_unwind *
+x86_64_frame_p (CORE_ADDR pc)
+{
+  return &x86_64_frame_unwind;
+}
+\f
+
+/* Signal trampolines.  */
+
+/* FIXME: kettenis/20030419: Perhaps, we can unify the 32-bit and
+   64-bit variants.  This would require using identical frame caches
+   on both platforms.  */
+
+static struct x86_64_frame_cache *
+x86_64_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache)
+{
+  struct x86_64_frame_cache *cache;
+  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  CORE_ADDR addr;
+  char buf[8];
+
+  if (*this_cache)
+    return *this_cache;
+
+  cache = x86_64_alloc_frame_cache ();
+
+  frame_unwind_register (next_frame, X86_64_RSP_REGNUM, buf);
+  cache->base = extract_unsigned_integer (buf, 8) - 8;
+
+  addr = tdep->sigcontext_addr (next_frame);
+  cache->saved_regs[X86_64_RIP_REGNUM] = addr + tdep->sc_pc_offset;
+  cache->saved_regs[X86_64_RSP_REGNUM] = addr + tdep->sc_sp_offset;
+
+  *this_cache = cache;
+  return cache;
+}
+
+static void
+x86_64_sigtramp_frame_this_id (struct frame_info *next_frame,
+			       void **this_cache, struct frame_id *this_id)
+{
+  struct x86_64_frame_cache *cache =
+    x86_64_sigtramp_frame_cache (next_frame, this_cache);
+
+  (*this_id) = frame_id_build (cache->base, frame_pc_unwind (next_frame));
 }
 
 static void
+x86_64_sigtramp_frame_prev_register (struct frame_info *next_frame,
+				     void **this_cache,
+				     int regnum, int *optimizedp,
+				     enum lval_type *lvalp, CORE_ADDR *addrp,
+				     int *realnump, void *valuep)
+{
+  /* Make sure we've initialized the cache.  */
+  x86_64_sigtramp_frame_cache (next_frame, this_cache);
+
+  x86_64_frame_prev_register (next_frame, this_cache, regnum,
+			      optimizedp, lvalp, addrp, realnump, valuep);
+}
+
+static const struct frame_unwind x86_64_sigtramp_frame_unwind =
+{
+  SIGTRAMP_FRAME,
+  x86_64_sigtramp_frame_this_id,
+  x86_64_sigtramp_frame_prev_register
+};
+
+static const struct frame_unwind *
+x86_64_sigtramp_frame_p (CORE_ADDR pc)
+{
+  char *name;
+
+  find_pc_partial_function (pc, &name, NULL, NULL);
+  if (PC_IN_SIGTRAMP (pc, name))
+    return &x86_64_sigtramp_frame_unwind;
+
+  return NULL;
+}
+\f
+
+static CORE_ADDR
+x86_64_frame_base_address (struct frame_info *next_frame, void **this_cache)
+{
+  struct x86_64_frame_cache *cache =
+    x86_64_frame_cache (next_frame, this_cache);
+
+  return cache->base;
+}
+
+static const struct frame_base x86_64_frame_base =
+{
+  &x86_64_frame_unwind,
+  x86_64_frame_base_address,
+  x86_64_frame_base_address,
+  x86_64_frame_base_address
+};
+
+static void
 x86_64_save_dummy_frame_tos (CORE_ADDR sp)
 {
-  /* We must add the size of the return address that is already 
-     put on the stack.  */
-  generic_save_dummy_frame_tos (sp + 
-				TYPE_LENGTH (builtin_type_void_func_ptr));
+  generic_save_dummy_frame_tos (sp + 16);
 }
 
 static struct frame_id
-x86_64_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *frame)
+x86_64_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
-  CORE_ADDR base;
-  frame_unwind_unsigned_register (frame, SP_REGNUM, &base);
-  return frame_id_build (base, frame_pc_unwind (frame));
+  char buf[8];
+  CORE_ADDR fp;
+
+  frame_unwind_register (next_frame, X86_64_RBP_REGNUM, buf);
+  fp = extract_unsigned_integer (buf, 8);
+
+  return frame_id_build (fp, frame_pc_unwind (next_frame));
 }
 
 void
@@ -932,115 +1158,107 @@ x86_64_init_abi (struct gdbarch_info inf
   set_gdbarch_long_double_bit (gdbarch, 128);
 
   set_gdbarch_num_regs (gdbarch, X86_64_NUM_REGS);
+  set_gdbarch_register_bytes (gdbarch, x86_64_register_bytes);
+  set_gdbarch_register_name (gdbarch, x86_64_register_name);
+  set_gdbarch_register_size (gdbarch, 8);
+  set_gdbarch_register_type (gdbarch, x86_64_register_type);
 
   /* Register numbers of various important registers.  */
-  set_gdbarch_sp_regnum (gdbarch, 7); /* %rsp */
-  set_gdbarch_deprecated_fp_regnum (gdbarch, 6); /* %rbp */
-  set_gdbarch_pc_regnum (gdbarch, 16); /* %rip */
-  set_gdbarch_ps_regnum (gdbarch, 17); /* %eflags */
-  set_gdbarch_fp0_regnum (gdbarch, X86_64_NUM_GREGS); /* %st(0) */
+  set_gdbarch_sp_regnum (gdbarch, X86_64_RSP_REGNUM); /* %rsp */
+  set_gdbarch_pc_regnum (gdbarch, X86_64_RIP_REGNUM); /* %rip */
+  set_gdbarch_ps_regnum (gdbarch, X86_64_EFLAGS_REGNUM); /* %eflags */
+  set_gdbarch_fp0_regnum (gdbarch, X86_64_ST0_REGNUM); /* %st(0) */
 
   /* The "default" register numbering scheme for the x86-64 is
-     referred to as the "DWARF register number mapping" in the psABI.
-     The preferred debugging format for all known x86-64 targets is
-     actually DWARF2, and GCC doesn't seem to support DWARF (that is
-     DWARF-1), but we provide the same mapping just in case.  This
-     mapping is also used for stabs, which GCC does support.  */
-  set_gdbarch_stab_reg_to_regnum (gdbarch, x86_64_dwarf2_reg_to_regnum);
-  set_gdbarch_dwarf_reg_to_regnum (gdbarch, x86_64_dwarf2_reg_to_regnum);
-  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, x86_64_dwarf2_reg_to_regnum);
+     referred to as the "DWARF Register Number Mapping" in the System
+     V psABI.  The preferred debugging format for all known x86-64
+     targets is actually DWARF2, and GCC doesn't seem to support DWARF
+     (that is DWARF-1), but we provide the same mapping just in case.
+     This mapping is also used for stabs, which GCC does support.  */
+  set_gdbarch_stab_reg_to_regnum (gdbarch, x86_64_dwarf_reg_to_regnum);
+  set_gdbarch_dwarf_reg_to_regnum (gdbarch, x86_64_dwarf_reg_to_regnum);
+  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, x86_64_dwarf_reg_to_regnum);
 
-  /* We don't override SDB_REG_RO_REGNUM, sice COFF doesn't seem to be
-     in use on any of the supported x86-64 targets.  */
+  /* We don't override SDB_REG_RO_REGNUM, since COFF doesn't seem to
+     be in use on any of the supported x86-64 targets.  */
 
-  set_gdbarch_register_name (gdbarch, x86_64_register_name);
-  set_gdbarch_register_size (gdbarch, 8);
-
-  /* Total amount of space needed to store our copies of the machine's
-     register (SIZEOF_GREGS + SIZEOF_FPU_REGS + SIZEOF_FPU_CTRL_REGS +
-     SIZEOF_SSE_REGS) */
-  for (i = 0, sum = 0; i < X86_64_NUM_REGS; i++)
-    sum += x86_64_register_info_table[i].size;
-  set_gdbarch_register_bytes (gdbarch, sum);
-
-  set_gdbarch_register_raw_size (gdbarch, x86_64_register_raw_size);
-  set_gdbarch_register_byte (gdbarch, x86_64_register_byte);
-  set_gdbarch_register_virtual_type (gdbarch, x86_64_register_virtual_type);
-
-  set_gdbarch_register_convertible (gdbarch, x86_64_register_convertible);
-  set_gdbarch_register_convert_to_virtual (gdbarch,
-					   x86_64_register_convert_to_virtual);
-  set_gdbarch_register_convert_to_raw (gdbarch,
-				       x86_64_register_convert_to_raw);
-
-  /* Getting saved registers is handled by unwind information.  */
-  set_gdbarch_deprecated_get_saved_register (gdbarch, cfi_get_saved_register);
-
-  /* FIXME: kettenis/20021026: Should we set parm_boundary to 64 here?  */
-  set_gdbarch_deprecated_target_read_fp (gdbarch, cfi_read_fp);
+  /* Call dummy code.  */
+  set_gdbarch_push_dummy_call (gdbarch, x86_64_push_dummy_call);
 
   set_gdbarch_extract_return_value (gdbarch, x86_64_extract_return_value);
-
-  set_gdbarch_deprecated_push_arguments (gdbarch, x86_64_push_arguments);
-  set_gdbarch_deprecated_push_return_address (gdbarch, x86_64_push_return_address);
-  set_gdbarch_deprecated_pop_frame (gdbarch, x86_64_pop_frame);
-  set_gdbarch_deprecated_store_struct_return (gdbarch, x86_64_store_struct_return);
   set_gdbarch_store_return_value (gdbarch, x86_64_store_return_value);
   /* Override, since this is handled by x86_64_extract_return_value.  */
   set_gdbarch_extract_struct_value_address (gdbarch, NULL);
   set_gdbarch_use_struct_convention (gdbarch, x86_64_use_struct_convention);
 
-  set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, x86_64_frame_init_saved_regs);
   set_gdbarch_skip_prologue (gdbarch, x86_64_skip_prologue);
 
-  set_gdbarch_deprecated_frame_chain (gdbarch, x86_64_linux_frame_chain);
-  set_gdbarch_frameless_function_invocation (gdbarch,
-					 x86_64_frameless_function_invocation);
-  /* FIXME: kettenis/20021026: These two are GNU/Linux-specific and
-     should be moved elsewhere.  */
-  set_gdbarch_deprecated_frame_saved_pc (gdbarch, x86_64_linux_frame_saved_pc);
-  set_gdbarch_deprecated_saved_pc_after_call (gdbarch, x86_64_linux_saved_pc_after_call);
-  set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
-  /* FIXME: kettenis/20021026: This one is GNU/Linux-specific too.  */
-  set_gdbarch_pc_in_sigtramp (gdbarch, x86_64_linux_in_sigtramp);
-
+  /* Avoid wiring in the MMX registers for now.  */
   set_gdbarch_num_pseudo_regs (gdbarch, 0);
 
-  /* Build call frame information (CFI) from DWARF2 frame debug info.  */
-  set_gdbarch_dwarf2_build_frame_info (gdbarch, dwarf2_build_frame_info);
-
-  /* Initialization of per-frame CFI.  */
-  set_gdbarch_deprecated_init_extra_frame_info (gdbarch, cfi_init_extra_frame_info);
-
-  /* Frame PC initialization is handled by using CFI.  */
-  set_gdbarch_deprecated_init_frame_pc (gdbarch, x86_64_init_frame_pc);
-
-  /* Cons up virtual frame pointer for trace.  */
-  set_gdbarch_virtual_frame_pointer (gdbarch, cfi_virtual_frame_pointer);
+  set_gdbarch_unwind_dummy_id (gdbarch, x86_64_unwind_dummy_id);
+  set_gdbarch_save_dummy_frame_tos (gdbarch, x86_64_save_dummy_frame_tos);
 
   /* FIXME: kettenis/20021026: This is ELF-specific.  Fine for now,
      since all supported x86-64 targets are ELF, but that might change
      in the future.  */
   set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section);
-  
-  /* Dummy frame helper functions.  */
-  set_gdbarch_save_dummy_frame_tos (gdbarch, x86_64_save_dummy_frame_tos);
-  set_gdbarch_unwind_dummy_id (gdbarch, x86_64_unwind_dummy_id);
+
+  frame_unwind_append_predicate (gdbarch, x86_64_sigtramp_frame_p);
+  frame_unwind_append_predicate (gdbarch, x86_64_frame_p);
+  frame_base_set_default (gdbarch, &x86_64_frame_base);
 }
 
 void
 _initialize_x86_64_tdep (void)
 {
-  /* Initialize the table saying where each register starts in the
-     register file.  */
-  {
-    int i, offset;
+  int i;
 
-    offset = 0;
-    for (i = 0; i < X86_64_NUM_REGS; i++)
-      {
-	x86_64_register_byte_table[i] = offset;
-	offset += x86_64_register_info_table[i].size;
-      }
-  }
+  /* Total amount of space needed to store our copies of the machine's
+     registers.  */
+  for (i = 0; i < X86_64_NUM_REGS; i++)
+    x86_64_register_bytes += TYPE_LENGTH (*x86_64_register_info[i].type);
+}
+\f
+
+#define I387_FISEG_REGNUM FISEG_REGNUM
+#define I387_FOSEG_REGNUM FOSEG_REGNUM
+
+/* The 64-bit FXSAVE format differs from the 32-bit format in the
+   sense that the instruction pointer and data pointer are simply
+   64-bit offsets into the code segment and the data segment instead
+   of a selector offset pair.  The functions below store the upper 32
+   bits of these pointers (instead of just the 16-bits of the segment
+   selector).  */
+
+/* Fill GDB's register array with the floating-point and SSE register
+   values in *FXSAVE.  This function masks off any of the reserved
+   bits in *FXSAVE.  */
+
+void
+x86_64_supply_fxsave (char *fxsave)
+{
+  i387_supply_fxsave (fxsave);
+
+  if (fxsave)
+    {
+      supply_register (I387_FISEG_REGNUM, fxsave + 12);
+      supply_register (I387_FOSEG_REGNUM, fxsave + 20);
+    }
+}
+
+/* Fill register REGNUM (if it is a floating-point or SSE register) in
+   *FXSAVE with the value in GDB's register array.  If REGNUM is -1, do
+   this for all registers.  This function doesn't touch any of the
+   reserved bits in *FXSAVE.  */
+
+void
+x86_64_fill_fxsave (char *fxsave, int regnum)
+{
+  i387_fill_fxsave (fxsave, regnum);
+
+  if (regnum == -1 || regnum == I387_FISEG_REGNUM)
+    regcache_collect (regnum, fxsave + 12);
+  if (regnum == -1 || regnum == I387_FOSEG_REGNUM)
+    regcache_collect (regnum, fxsave + 20);
 }
Index: x86-64-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/x86-64-tdep.h,v
retrieving revision 1.14
diff -u -p -r1.14 x86-64-tdep.h
--- x86-64-tdep.h 12 Apr 2003 17:41:26 -0000 1.14
+++ x86-64-tdep.h 17 May 2003 14:58:43 -0000
@@ -1,6 +1,8 @@
-/* Target-dependent code for GDB, the GNU debugger.
-   Copyright 2001
+/* Target-dependent code for the x86-64.
+
+   Copyright 2001, 2003
    Free Software Foundation, Inc.
+
    Contributed by Jiri Smid, SuSE Labs.
 
    This file is part of GDB.
@@ -28,19 +30,22 @@ struct frame_info;
 
 #include "i386-tdep.h"
 
-extern int x86_64_num_regs;
-extern int x86_64_num_gregs;
+/* Number of general purpose registers.  */
+#define X86_64_NUM_GREGS	22
+
+void x86_64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch);
 
-int x86_64_register_number (const char *name);
-const char *x86_64_register_name (int reg_nr);
+/* Fill GDB's register array with the floating-point and SSE register
+   values in *FXSAVE.  This function masks off any of the reserved
+   bits in *FXSAVE.  */
 
-gdbarch_deprecated_frame_saved_pc_ftype x86_64_linux_frame_saved_pc;
-gdbarch_deprecated_saved_pc_after_call_ftype x86_64_linux_saved_pc_after_call;
-gdbarch_pc_in_sigtramp_ftype x86_64_linux_in_sigtramp;
-CORE_ADDR x86_64_linux_frame_chain (struct frame_info *fi);
-CORE_ADDR x86_64_init_frame_pc (int fromleaf, struct frame_info *fi);
-int x86_64_function_has_prologue (CORE_ADDR pc);
+void x86_64_supply_fxsave (char *fxsave);
 
-void x86_64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch);
+/* Fill register REGNUM (if it is a floating-point or SSE register) in
+   *FXSAVE with the value in GDB's register array.  If REGNUM is -1, do
+   this for all registers.  This function doesn't touch any of the
+   reserved bits in *FXSAVE.  */
+
+void x86_64_fill_fxsave (char *fxsave, int regnum);
 
-#endif
+#endif /* x86-64-tdep.h */
Index: config/i386/nm-x86-64linux.h
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/nm-x86-64linux.h,v
retrieving revision 1.1
diff -u -p -r1.1 nm-x86-64linux.h
--- config/i386/nm-x86-64linux.h 1 Jul 2002 22:09:52 -0000 1.1
+++ config/i386/nm-x86-64linux.h 17 May 2003 14:58:43 -0000
@@ -1,7 +1,8 @@
 /* Native support for GNU/Linux x86-64.
 
-   Copyright 2001, 2002 Free Software Foundation, Inc.  Contributed by
-   Jiri Smid, SuSE Labs.
+   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+   Contributed by Jiri Smid, SuSE Labs.
 
    This file is part of GDB.
 
@@ -20,13 +21,14 @@
    Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#ifndef NM_X86_64_H
-#define NM_X86_64_H
-
-#include "config/nm-linux.h"
+#ifndef NM_X86_64_LINUX_H
+#define NM_X86_64_LINUX_H
 
+/* GNU/Linux supports the i386 hradware debugging registers.  */
 #define I386_USE_GENERIC_WATCHPOINTS
+
 #include "i386/nm-i386.h"
+#include "config/nm-linux.h"
 
 /* Support for 8-byte wide hw watchpoints.  */
 #define TARGET_HAS_DR_LEN_8 1
@@ -50,41 +52,17 @@ extern unsigned long x86_64_linux_dr_get
   x86_64_linux_dr_get_status ()
 \f
 
-#define REGISTER_U_ADDR(addr, blockend, regno) \
-	(addr) = x86_64_register_u_addr ((blockend),(regno));
-CORE_ADDR x86_64_register_u_addr (CORE_ADDR, int);
-
-/* Return the size of the user struct.  */
-#define KERNEL_U_SIZE kernel_u_size()
-extern int kernel_u_size (void);
-
-/* Offset of the registers within the user area.  */
-#define U_REGS_OFFSET 0
-
-/* This is the amount to subtract from u.u_ar0
-   to get the offset in the core file of the register values.  */
-#define KERNEL_U_ADDR 0x0
+/* Type of the third argument to the `ptrace' system call.  */
+#define PTRACE_ARG3_TYPE long
 
-#define PTRACE_ARG3_TYPE void*
-#define PTRACE_XFER_TYPE unsigned long
-\f
-
-/* We define this if link.h is available, because with ELF we use SVR4 style
-   shared libraries. */
-
-#ifdef HAVE_LINK_H
-#define SVR4_SHARED_LIBS
-#include "solib.h"		/* Support for shared libraries. */
-#endif
+/* Type of the fourth argument to the `ptrace' system call.  */
+#define PTRACE_XFER_TYPE long
 
 /* Override copies of {fetch,store}_inferior_registers in `infptrace.c'.  */
 #define FETCH_INFERIOR_REGISTERS
+\f
 
+/* FIXME: kettenis/20030416: Why?  */
 #undef PREPARE_TO_PROCEED
 
-#include <signal.h>
-
-extern void lin_thread_get_thread_signals (sigset_t * mask);
-#define GET_THREAD_SIGNALS(mask) lin_thread_get_thread_signals (mask)
-
-#endif /* NM_X86_64.h */
+#endif /* NM_X86_64_LINUX_H */
Index: config/i386/tm-x86-64linux.h
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/tm-x86-64linux.h,v
retrieving revision 1.1
diff -u -p -r1.1 tm-x86-64linux.h
--- config/i386/tm-x86-64linux.h 1 Jul 2002 22:09:52 -0000 1.1
+++ config/i386/tm-x86-64linux.h 17 May 2003 14:58:43 -0000
@@ -1,6 +1,6 @@
 /* Definitions to target GDB to GNU/Linux on x86-64.
 
-   Copyright 2002 Free Software Foundation, Inc.
+   Copyright 2002, 2003 Free Software Foundation, Inc.
 
    Contributed by Michal Ludvig, SuSE Labs.
 
@@ -25,10 +25,10 @@
 #define TM_X86_64LINUX_H
 
 /* We define SVR4_SHARED_LIBS unconditionally, on the assumption that
- * link.h is available on all linux platforms.  For I386 and SH3/4, 
- * we hard-code the information rather than use link.h anyway (for 
- * the benefit of cross-debugging).  We may move to doing that for
- * other architectures as well.  */
+   link.h is available on all linux platforms.  For I386 and SH3/4, we
+   hard-code the information rather than use link.h anyway (for the
+   benefit of cross-debugging).  We may move to doing that for other
+   architectures as well.  */
 
 #define SVR4_SHARED_LIBS
 #include "solib.h"              /* Support for shared libraries. */
Index: config/i386/x86-64linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/x86-64linux.mh,v
retrieving revision 1.7
diff -u -p -r1.7 x86-64linux.mh
--- config/i386/x86-64linux.mh 1 Jul 2002 22:09:52 -0000 1.7
+++ config/i386/x86-64linux.mh 17 May 2003 14:58:43 -0000
@@ -4,8 +4,9 @@ XM_FILE= xm-i386.h
 
 NAT_FILE= nm-x86-64linux.h
 NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o \
-	core-aout.o i386-nat.o x86-64-linux-nat.o \
-	proc-service.o thread-db.o lin-lwp.o \
-	linux-proc.o gcore.o 
+	core-regset.o i386-nat.o x86-64-linux-nat.o \
+	proc-service.o thread-db.o lin-lwp.o inux-proc.o gcore.o 
 
+# The dynamically loaded libthread_db needs access to symbols in the
+# gdb executable.
 LOADLIBES = -ldl -rdynamic
Index: config/i386/x86-64linux.mt
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/x86-64linux.mt,v
retrieving revision 1.6
diff -u -p -r1.6 x86-64linux.mt
--- config/i386/x86-64linux.mt 21 Dec 2002 21:09:58 -0000 1.6
+++ config/i386/x86-64linux.mt 17 May 2003 14:58:43 -0000
@@ -1,8 +1,5 @@
 # Target: AMD x86-64 running GNU/Linux
-TDEPFILES= x86-64-tdep.o x86-64-linux-tdep.o dwarf2cfi.o \
+TDEPFILES= x86-64-tdep.o x86-64-linux-tdep.o \
 	i386-tdep.o i387-tdep.o \
 	solib.o solib-svr4.o solib-legacy.o
-
-GDB_MULTI_ARCH=GDB_MULTI_ARCH_TM
-
 TM_FILE=tm-x86-64linux.h


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

end of thread, other threads:[~2003-05-20  5:49 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-05-17 18:34 [PATCH/i386newframe] amd64newframe Andreas Jaeger
2003-05-17 22:26 ` Mark Kettenis
2003-05-19  7:00   ` Michal Ludvig
2003-05-19  7:09     ` Andreas Jaeger
2003-05-19 17:15       ` Mark Kettenis
2003-05-19 19:54         ` Elena Zannoni
2003-05-19 22:31           ` Elena Zannoni
2003-05-20  5:49         ` Michal Ludvig
  -- strict thread matches above, loose matches on Subject: below --
2003-05-17 15:19 Mark Kettenis
2003-05-19 15:31 ` Elena Zannoni
2003-05-19 17:11   ` Mark Kettenis
2003-05-19 21:24     ` Michal Ludvig
2003-05-19 21:40       ` Daniel Jacobowitz
2003-05-19 22:24       ` Elena Zannoni

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