Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [RFC] i386/amd64 biarch gdbserver
@ 2009-05-09 19:12 Doug Evans
  2009-05-11 17:50 ` Pedro Alves
  0 siblings, 1 reply; 4+ messages in thread
From: Doug Evans @ 2009-05-09 19:12 UTC (permalink / raw)
  To: gdb-patches

Hi.

This patch implements biarch i386/amd64 gdbserver.

I haven't done anything with xml target descriptions, but there
are no regressions so it seems like a good stopping place.

This patch also fixes a bug where current amd64 gdbserver
doesn't handle xmm[8-15].  Testcase to follow later.

Tested on
- i386-linux
- x86_64-linux with gcc -m64
- x86_64-linux with gcc -m32 (and hacking site.exp to specify i386-linux)
using --target_board=native-gdbserver
[ref http://sourceware.org/gdb/wiki/Native_gdbserver_testing]

Comments?

2009-05-09  Doug Evans  <dje@google.com>

	Biarch support for i386/amd64 gdbserver.
	* Makefile.in (SFILES): Remove linux-i386-low.c, linux-x86-64-low.c.
	Add linux-x86-low.c.
	(linux-i386-low.o, linux-x86-64-low.o): Delete.
	(linux-x86-low.o): Add.
	* linux-x86-64-low.c: Delete.
	* linux-i386-low.c: Delete.
	* linux-x86-low.c: New file.
	* configure.srv (i?86-linux srv_tgtobj): Replace linux-i386-low.o with
	linux-x86-low.o.
	(x86_64-linux srv_tgtobj): Replace linux-x86-64-low.o with
	linux-x86-low.o.
	(x86_64-linux srv_regobj): Add reg-i386-linux.o.
	* linux-low.c: Include ansidecl.h, elf/common.h, elf/external.h.
	(linux_child_pid_to_exec_file): New function.
	(elf_64_header_p, elf_64_file_p): New functions.
	(siginfo_fixup): New function.
	(linux_xfer_siginfo): New local inf_siginfo.  Call siginfo_fixup to
	give target a chance to convert layout.
	* linux-low.h (linux_target_ops): New member siginfo_fixup.
	(linux_child_pid_to_exec_file, elf_64_file_p): Declare.

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/Makefile.in,v
retrieving revision 1.73
diff -u -p -r1.73 Makefile.in
--- Makefile.in	1 Apr 2009 22:48:05 -0000	1.73
+++ Makefile.in	9 May 2009 19:08:23 -0000
@@ -103,7 +103,7 @@ SFILES=	$(srcdir)/gdbreplay.c $(srcdir)/
 	$(srcdir)/remote-utils.c $(srcdir)/server.c $(srcdir)/target.c \
 	$(srcdir)/thread-db.c $(srcdir)/utils.c \
 	$(srcdir)/linux-arm-low.c $(srcdir)/linux-cris-low.c \
-	$(srcdir)/linux-crisv32-low.c $(srcdir)/linux-i386-low.c \
+	$(srcdir)/linux-crisv32-low.c \
 	$(srcdir)/i387-fp.c \
 	$(srcdir)/linux-ia64-low.c $(srcdir)/linux-low.c \
 	$(srcdir)/linux-m32r-low.c \
@@ -111,7 +111,7 @@ SFILES=	$(srcdir)/gdbreplay.c $(srcdir)/
 	$(srcdir)/linux-ppc-low.c \
 	$(srcdir)/linux-s390-low.c \
 	$(srcdir)/linux-sh-low.c $(srcdir)/linux-sparc-low.c \
-	$(srcdir)/linux-x86-64-low.c \
+	$(srcdir)/linux-x86-low.c \
 	$(srcdir)/linux-xtensa-low.c \
 	$(srcdir)/win32-arm-low.c $(srcdir)/win32-i386-low.c \
 	$(srcdir)/win32-low.c $(srcdir)/wincecompat.c \
@@ -296,8 +296,6 @@ linux-arm-low.o: linux-arm-low.c $(linux
 	$(gdb_proc_service_h)
 linux-cris-low.o: linux-cris-low.c $(linux_low_h) $(server_h)
 linux-crisv32-low.o: linux-crisv32-low.c $(linux_low_h) $(server_h)
-linux-i386-low.o: linux-i386-low.c $(linux_low_h) $(server_h) \
-	$(gdb_proc_service_h)
 linux-ia64-low.o: linux-ia64-low.c $(linux_low_h) $(server_h)
 linux-m32r-low.o: linux-m32r-low.c $(linux_low_h) $(server_h)
 linux-mips-low.o: linux-mips-low.c $(linux_low_h) $(server_h) \
@@ -305,7 +303,7 @@ linux-mips-low.o: linux-mips-low.c $(lin
 linux-ppc-low.o: linux-ppc-low.c $(linux_low_h) $(server_h)
 linux-s390-low.o: linux-s390-low.c $(linux_low_h) $(server_h)
 linux-sh-low.o: linux-sh-low.c $(linux_low_h) $(server_h)
-linux-x86-64-low.o: linux-x86-64-low.c $(linux_low_h) $(server_h) \
+linux-x86-low.o: linux-x86-low.c $(linux_low_h) $(server_h) \
 	$(gdb_proc_service_h)
 linux-xtensa-low.o: linux-xtensa-low.c xtensa-xtregs.c $(linux_low_h) $(server_h)
 
Index: configure.srv
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/configure.srv,v
retrieving revision 1.40
diff -u -p -r1.40 configure.srv
--- configure.srv	19 Apr 2009 17:54:52 -0000	1.40
+++ configure.srv	9 May 2009 18:49:29 -0000
@@ -56,7 +56,7 @@ case "${target}" in
 			srv_tgtobj="win32-low.o win32-i386-low.o"
 			;;
   i[34567]86-*-linux*)	srv_regobj=reg-i386-linux.o
-			srv_tgtobj="linux-low.o linux-i386-low.o i387-fp.o"
+			srv_tgtobj="linux-low.o linux-x86-low.o i387-fp.o"
 			srv_linux_usrregs=yes
 			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
@@ -169,8 +169,9 @@ case "${target}" in
   spu*-*-*)		srv_regobj=reg-spu.o
 			srv_tgtobj="spu-low.o"
 			;;
-  x86_64-*-linux*)	srv_regobj=reg-x86-64-linux.o
-			srv_tgtobj="linux-low.o linux-x86-64-low.o i387-fp.o"
+  x86_64-*-linux*)	srv_regobj="reg-x86-64-linux.o reg-i386-linux.o"
+			srv_tgtobj="linux-low.o linux-x86-low.o i387-fp.o"
+			srv_linux_usrregs=yes # This is for i386 progs.
 			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
 			;;
Index: linux-i386-low.c
===================================================================
RCS file: linux-i386-low.c
diff -N linux-i386-low.c
--- linux-i386-low.c	22 Mar 2009 23:57:10 -0000	1.19
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,210 +0,0 @@
-/* GNU/Linux/i386 specific low level interface, for the remote server for GDB.
-   Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006,
-   2007, 2008, 2009 Free Software Foundation, Inc.
-
-   This file is part of GDB.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-#include "server.h"
-#include "linux-low.h"
-#include "i387-fp.h"
-
-#include "gdb_proc_service.h"
-
-#include <sys/ptrace.h>
-
-#ifdef HAVE_SYS_REG_H
-#include <sys/reg.h>
-#endif
-
-#ifndef PTRACE_GET_THREAD_AREA
-#define PTRACE_GET_THREAD_AREA 25
-#endif
-
-/* Defined in auto-generated file reg-i386-linux.c.  */
-void init_registers_i386_linux (void);
-
-
-/* This module only supports access to the general purpose registers.  */
-
-#define i386_num_regs 16
-
-/* This stuff comes from i386-linux-nat.c.  */
-
-/* Mapping between the general-purpose registers in `struct user'
-   format and GDB's register array layout.  */
-static int i386_regmap[] =
-{
-  EAX * 4, ECX * 4, EDX * 4, EBX * 4,
-  UESP * 4, EBP * 4, ESI * 4, EDI * 4,
-  EIP * 4, EFL * 4, CS * 4, SS * 4,
-  DS * 4, ES * 4, FS * 4, GS * 4
-};
-
-/* Called by libthread_db.  */
-
-ps_err_e
-ps_get_thread_area (const struct ps_prochandle *ph,
-		    lwpid_t lwpid, int idx, void **base)
-{
-  unsigned int desc[4];
-
-  if (ptrace (PTRACE_GET_THREAD_AREA, lwpid,
-	      (void *) idx, (unsigned long) &desc) < 0)
-    return PS_ERR;
-
-  *(int *)base = desc[1];
-  return PS_OK;
-}
-
-static int
-i386_cannot_store_register (int regno)
-{
-  return (regno >= i386_num_regs);
-}
-
-static int
-i386_cannot_fetch_register (int regno)
-{
-  return (regno >= i386_num_regs);
-}
-
-
-#ifdef HAVE_PTRACE_GETREGS
-#include <sys/procfs.h>
-#include <sys/ptrace.h>
-
-static void
-i386_fill_gregset (void *buf)
-{
-  int i;
-
-  for (i = 0; i < i386_num_regs; i++)
-    collect_register (i, ((char *) buf) + i386_regmap[i]);
-
-  collect_register_by_name ("orig_eax", ((char *) buf) + ORIG_EAX * 4);
-}
-
-static void
-i386_store_gregset (const void *buf)
-{
-  int i;
-
-  for (i = 0; i < i386_num_regs; i++)
-    supply_register (i, ((char *) buf) + i386_regmap[i]);
-
-  supply_register_by_name ("orig_eax", ((char *) buf) + ORIG_EAX * 4);
-}
-
-static void
-i386_fill_fpregset (void *buf)
-{
-  i387_cache_to_fsave (buf);
-}
-
-static void
-i386_store_fpregset (const void *buf)
-{
-  i387_fsave_to_cache (buf);
-}
-
-static void
-i386_fill_fpxregset (void *buf)
-{
-  i387_cache_to_fxsave (buf);
-}
-
-static void
-i386_store_fpxregset (const void *buf)
-{
-  i387_fxsave_to_cache (buf);
-}
-
-#endif /* HAVE_PTRACE_GETREGS */
-
-struct regset_info target_regsets[] = {
-#ifdef HAVE_PTRACE_GETREGS
-  { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t),
-    GENERAL_REGS,
-    i386_fill_gregset, i386_store_gregset },
-# ifdef HAVE_PTRACE_GETFPXREGS
-  { PTRACE_GETFPXREGS, PTRACE_SETFPXREGS, sizeof (elf_fpxregset_t),
-    EXTENDED_REGS,
-    i386_fill_fpxregset, i386_store_fpxregset },
-# endif
-  { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof (elf_fpregset_t),
-    FP_REGS,
-    i386_fill_fpregset, i386_store_fpregset },
-#endif /* HAVE_PTRACE_GETREGS */
-  { 0, 0, -1, -1, NULL, NULL }
-};
-
-static const unsigned char i386_breakpoint[] = { 0xCC };
-#define i386_breakpoint_len 1
-
-extern int debug_threads;
-
-static CORE_ADDR
-i386_get_pc ()
-{
-  unsigned long pc;
-
-  collect_register_by_name ("eip", &pc);
-
-  if (debug_threads)
-    fprintf (stderr, "stop pc (before any decrement) is %08lx\n", pc);
-  return pc;
-}
-
-static void
-i386_set_pc (CORE_ADDR newpc)
-{
-  if (debug_threads)
-    fprintf (stderr, "set pc to %08lx\n", (long) newpc);
-  supply_register_by_name ("eip", &newpc);
-}
-
-static int
-i386_breakpoint_at (CORE_ADDR pc)
-{
-  unsigned char c;
-
-  read_inferior_memory (pc, &c, 1);
-  if (c == 0xCC)
-    return 1;
-
-  return 0;
-}
-
-struct linux_target_ops the_low_target = {
-  init_registers_i386_linux,
-  i386_num_regs,
-  i386_regmap,
-  i386_cannot_fetch_register,
-  i386_cannot_store_register,
-  i386_get_pc,
-  i386_set_pc,
-  i386_breakpoint,
-  i386_breakpoint_len,
-  NULL,
-  1,
-  i386_breakpoint_at,
-  NULL,
-  NULL,
-  NULL,
-  NULL,
-  NULL,
-  NULL,
-};
Index: linux-low.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/linux-low.c,v
retrieving revision 1.100
diff -u -p -r1.100 linux-low.c
--- linux-low.c	7 May 2009 23:29:25 -0000	1.100
+++ linux-low.c	9 May 2009 18:49:30 -0000
@@ -19,6 +19,9 @@
 
 #include "server.h"
 #include "linux-low.h"
+#include "ansidecl.h" /* For ATTRIBUTE_PACKED, must be bug in external.h.  */
+#include "elf/common.h"
+#include "elf/external.h"
 
 #include <sys/wait.h>
 #include <stdio.h>
@@ -154,6 +157,68 @@ static int linux_event_pipe[2] = { -1, -
 static void send_sigstop (struct inferior_list_entry *entry);
 static void wait_for_sigstop (struct inferior_list_entry *entry);
 
+/* Accepts an integer PID; Returns a string representing a file that
+   can be opened to get info for the child process.
+   Space for the result is malloc'd, caller must free.  */
+
+char *
+linux_child_pid_to_exec_file (int pid)
+{
+  char *name1, *name2;
+
+  name1 = xmalloc (MAXPATHLEN);
+  name2 = xmalloc (MAXPATHLEN);
+  memset (name2, 0, MAXPATHLEN);
+
+  sprintf (name1, "/proc/%d/exe", pid);
+  if (readlink (name1, name2, MAXPATHLEN) > 0)
+    {
+      free (name1);
+      return name2;
+    }
+  else
+    {
+      free (name2);
+      return name1;
+    }
+}
+
+/* Return non-zero if HEADER is a 64-bit ELF file.  */
+
+static int
+elf_64_header_p (const Elf64_External_Ehdr *header)
+{
+  return (header->e_ident[EI_MAG0] == ELFMAG0
+          && header->e_ident[EI_MAG1] == ELFMAG1
+          && header->e_ident[EI_MAG2] == ELFMAG2
+          && header->e_ident[EI_MAG3] == ELFMAG3
+          && header->e_ident[EI_CLASS] == ELFCLASS64);
+}
+
+/* Return non-zero if FILE is a 64-bit ELF file,
+   zero if the file is not a 64-bit ELF file,
+   and -1 if the file is not accessible or doesn't exist.  */
+
+int
+elf_64_file_p (const char *file)
+{
+  Elf64_External_Ehdr header;
+  int fd;
+
+  fd = open (file, O_RDONLY);
+  if (fd < 0)
+    return -1;
+
+  if (read (fd, &header, sizeof (header)) != sizeof (header))
+    {
+      close (fd);
+      return 0;
+    }
+  close (fd);
+
+  return elf_64_header_p (&header);
+}
+
 static void
 delete_lwp (struct lwp_info *lwp)
 {
@@ -2786,12 +2853,35 @@ linux_qxfer_osdata (const char *annex,
   return len;
 }
 
+/* Convert a native/host siginfo object, into/from the siginfo in the
+   layout of the inferiors' architecture.  */
+
+static void
+siginfo_fixup (struct siginfo *siginfo, void *inf_siginfo, int direction)
+{
+  int done = 0;
+
+  if (the_low_target.siginfo_fixup != NULL)
+    done = the_low_target.siginfo_fixup (siginfo, inf_siginfo, direction);
+
+  /* If there was no callback, or the callback didn't do anything,
+     then just do a straight memcpy.  */
+  if (!done)
+    {
+      if (direction == 1)
+	memcpy (siginfo, inf_siginfo, sizeof (struct siginfo));
+      else
+	memcpy (inf_siginfo, siginfo, sizeof (struct siginfo));
+    }
+}
+
 static int
 linux_xfer_siginfo (const char *annex, unsigned char *readbuf,
 		    unsigned const char *writebuf, CORE_ADDR offset, int len)
 {
+  int pid;
   struct siginfo siginfo;
-  long pid = -1;
+  char inf_siginfo[sizeof (struct siginfo)];
 
   if (current_inferior == NULL)
     return -1;
@@ -2799,7 +2889,7 @@ linux_xfer_siginfo (const char *annex, u
   pid = lwpid_of (get_thread_lwp (current_inferior));
 
   if (debug_threads)
-    fprintf (stderr, "%s siginfo for lwp %ld.\n",
+    fprintf (stderr, "%s siginfo for lwp %d.\n",
 	     readbuf != NULL ? "Reading" : "Writing",
 	     pid);
 
@@ -2809,14 +2899,24 @@ linux_xfer_siginfo (const char *annex, u
   if (ptrace (PTRACE_GETSIGINFO, pid, 0, &siginfo) != 0)
     return -1;
 
+  /* When GDBSERVER is built as a 64-bit application, ptrace writes into
+     SIGINFO an object with 64-bit layout.  Since debugging a 32-bit
+     inferior with a 64-bit GDBSERVER should look the same as debugging it
+     with a 32-bit GDBSERVER, we need to convert it.  */
+  siginfo_fixup (&siginfo, inf_siginfo, 0);
+
   if (offset + len > sizeof (siginfo))
     len = sizeof (siginfo) - offset;
 
   if (readbuf != NULL)
-    memcpy (readbuf, (char *) &siginfo + offset, len);
+    memcpy (readbuf, inf_siginfo + offset, len);
   else
     {
-      memcpy ((char *) &siginfo + offset, writebuf, len);
+      memcpy (inf_siginfo + offset, writebuf, len);
+
+      /* Convert back to ptrace layout before flushing it out.  */
+      siginfo_fixup (&siginfo, inf_siginfo, 1);
+
       if (ptrace (PTRACE_SETSIGINFO, pid, 0, &siginfo) != 0)
 	return -1;
     }
Index: linux-low.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/linux-low.h,v
retrieving revision 1.29
diff -u -p -r1.29 linux-low.h
--- linux-low.h	6 May 2009 17:32:59 -0000	1.29
+++ linux-low.h	9 May 2009 18:49:30 -0000
@@ -43,6 +43,8 @@ struct regset_info
 extern struct regset_info target_regsets[];
 #endif
 
+struct siginfo;
+
 struct process_info_private
 {
   /* True if this process has loaded thread_db, and it is active.  */
@@ -75,7 +77,6 @@ struct linux_target_ops
   int breakpoint_len;
   CORE_ADDR (*breakpoint_reinsert_addr) (void);
 
-
   int decr_pc_after_break;
   int (*breakpoint_at) (CORE_ADDR pc);
 
@@ -89,6 +90,12 @@ struct linux_target_ops
      for registers smaller than an xfer unit).  */
   void (*collect_ptrace_register) (int regno, char *buf);
   void (*supply_ptrace_register) (int regno, const char *buf);
+
+  /* Hook to convert from target format to ptrace format and back.
+     Returns true if any conversion was done; false otherwise.
+     If DIRECTION is 1, then copy from INF to NATIVE.
+     If DIRECTION is 0, copy from NATIVE to INF.  */
+  int (*siginfo_fixup) (struct siginfo *native, void *inf, int direction);
 };
 
 extern struct linux_target_ops the_low_target;
@@ -169,6 +176,9 @@ struct lwp_info
 
 extern struct inferior_list all_lwps;
 
+char *linux_child_pid_to_exec_file (int pid);
+int elf_64_file_p (const char *file);
+
 void linux_attach_lwp (unsigned long pid);
 
 int thread_db_init (int use_events);
Index: linux-x86-64-low.c
===================================================================
RCS file: linux-x86-64-low.c
diff -N linux-x86-64-low.c
--- linux-x86-64-low.c	22 Mar 2009 23:57:10 -0000	1.22
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,184 +0,0 @@
-/* GNU/Linux/x86-64 specific low level interface, for the remote server
-   for GDB.
-   Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008, 2009
-   Free Software Foundation, Inc.
-
-   This file is part of GDB.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-#include "server.h"
-#include "linux-low.h"
-#include "i387-fp.h"
-
-#include "gdb_proc_service.h"
-
-/* Defined in auto-generated file reg-x86-64-linux.c.  */
-void init_registers_x86_64_linux (void);
-
-#include <sys/reg.h>
-#include <sys/procfs.h>
-#include <sys/ptrace.h>
-
-/* This definition comes from prctl.h, but some kernels may not have it.  */
-#ifndef PTRACE_ARCH_PRCTL
-#define PTRACE_ARCH_PRCTL      30
-#endif
-
-/* The following definitions come from prctl.h, but may be absent
-   for certain configurations.  */
-#ifndef ARCH_GET_FS
-#define ARCH_SET_GS 0x1001
-#define ARCH_SET_FS 0x1002
-#define ARCH_GET_FS 0x1003
-#define ARCH_GET_GS 0x1004
-#endif
-
-static int x86_64_regmap[] = {
-  RAX * 8, RBX * 8, RCX * 8, RDX * 8,
-  RSI * 8, RDI * 8, RBP * 8, RSP * 8,
-  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,
-  -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))
-
-/* Called by libthread_db.  */
-
-ps_err_e
-ps_get_thread_area (const struct ps_prochandle *ph,
-		    lwpid_t lwpid, int idx, void **base)
-{
-  switch (idx)
-    {
-    case FS:
-      if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0)
-	return PS_OK;
-      break;
-    case GS:
-      if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0)
-	return PS_OK;
-      break;
-    default:
-      return PS_BADADDR;
-    }
-  return PS_ERR;
-}
-
-static void
-x86_64_fill_gregset (void *buf)
-{
-  int i;
-
-  for (i = 0; i < X86_64_NUM_GREGS; i++)
-    if (x86_64_regmap[i] != -1)
-      collect_register (i, ((char *) buf) + x86_64_regmap[i]);
-}
-
-static void
-x86_64_store_gregset (const void *buf)
-{
-  int i;
-
-  for (i = 0; i < X86_64_NUM_GREGS; i++)
-    if (x86_64_regmap[i] != -1)
-      supply_register (i, ((char *) buf) + x86_64_regmap[i]);
-}
-
-static void
-x86_64_fill_fpregset (void *buf)
-{
-  i387_cache_to_fxsave (buf);
-}
-
-static void
-x86_64_store_fpregset (const void *buf)
-{
-  i387_fxsave_to_cache (buf);
-}
-
-struct regset_info target_regsets[] = {
-  { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t),
-    GENERAL_REGS,
-    x86_64_fill_gregset, x86_64_store_gregset },
-  { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof (elf_fpregset_t),
-    FP_REGS,
-    x86_64_fill_fpregset, x86_64_store_fpregset },
-  { 0, 0, -1, -1, NULL, NULL }
-};
-
-static const unsigned char x86_64_breakpoint[] = { 0xCC };
-#define x86_64_breakpoint_len 1
-
-extern int debug_threads;
-
-static CORE_ADDR
-x86_64_get_pc ()
-{
-  unsigned long pc;
-
-  collect_register_by_name ("rip", &pc);
-
-  if (debug_threads)
-    fprintf (stderr, "stop pc (before any decrement) is %08lx\n", pc);
-  return pc;
-}
-
-static void
-x86_64_set_pc (CORE_ADDR newpc)
-{
-  if (debug_threads)
-    fprintf (stderr, "set pc to %08lx\n", (long) newpc);
-  supply_register_by_name ("rip", &newpc);
-}
-
-static int
-x86_64_breakpoint_at (CORE_ADDR pc)
-{
-  unsigned char c;
-
-  read_inferior_memory (pc, &c, 1);
-  if (c == 0xCC)
-    return 1;
-
-  return 0;
-}
-
-struct linux_target_ops the_low_target = {
-  init_registers_x86_64_linux,
-  -1,
-  NULL,
-  NULL,
-  NULL,
-  x86_64_get_pc,
-  x86_64_set_pc,
-  x86_64_breakpoint,
-  x86_64_breakpoint_len,
-  NULL,
-  1,
-  x86_64_breakpoint_at,
-  NULL,
-  NULL,
-  NULL,
-  NULL,
-  NULL,
-  NULL,
-};
Index: linux-x86-low.c
===================================================================
RCS file: linux-x86-low.c
diff -N linux-x86-low.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ linux-x86-low.c	9 May 2009 18:49:30 -0000
@@ -0,0 +1,644 @@
+/* GNU/Linux/x86-64 specific low level interface, for the remote server
+   for GDB.
+   Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008, 2009
+   Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <signal.h>
+#include "server.h"
+#include "linux-low.h"
+#include "i387-fp.h"
+
+#include "gdb_proc_service.h"
+
+/* NOTE: gdb_proc_service.h may include linux/elf.h.
+   We need Elf32_Phdr.  If we don't get linux/elf.h we could include
+   elf.h like linux-ppc-low.c does.  */
+
+/* Defined in auto-generated file reg-i386-linux.c.  */
+void init_registers_i386_linux (void);
+/* Defined in auto-generated file reg-x86-64-linux.c.  */
+void init_registers_x86_64_linux (void);
+
+#include <sys/reg.h>
+#include <sys/procfs.h>
+#include <sys/ptrace.h>
+
+#ifndef PTRACE_GET_THREAD_AREA
+#define PTRACE_GET_THREAD_AREA 25
+#endif
+
+/* This definition comes from prctl.h, but some kernels may not have it.  */
+#ifndef PTRACE_ARCH_PRCTL
+#define PTRACE_ARCH_PRCTL      30
+#endif
+
+/* The following definitions come from prctl.h, but may be absent
+   for certain configurations.  */
+#ifndef ARCH_GET_FS
+#define ARCH_SET_GS 0x1001
+#define ARCH_SET_FS 0x1002
+#define ARCH_GET_FS 0x1003
+#define ARCH_GET_GS 0x1004
+#endif
+
+#ifdef __x86_64__
+
+/* Mapping between the general-purpose registers in `struct user'
+   format and GDB's register array layout.
+   Note that the transfer layout uses 64-bit regs.  */
+static /*const*/ int i386_regmap[] = 
+{
+  RAX * 8, RCX * 8, RDX * 8, RBX * 8,
+  RSP * 8, RBP * 8, RSI * 8, RDI * 8,
+  RIP * 8, EFLAGS * 8, CS * 8, SS * 8,
+  DS * 8, ES * 8, FS * 8, GS * 8
+};
+
+#define I386_NUM_REGS (sizeof (i386_regmap) / sizeof (i386_regmap[0]))
+
+/* So code below doesn't have to care, i386 or amd64.  */
+#define ORIG_EAX ORIG_RAX
+
+static const int x86_64_regmap[] =
+{
+  RAX * 8, RBX * 8, RCX * 8, RDX * 8,
+  RSI * 8, RDI * 8, RBP * 8, RSP * 8,
+  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,
+  -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_REGS (sizeof (x86_64_regmap) / sizeof (x86_64_regmap[0]))
+
+#else /* ! __x86_64__ */
+
+/* Mapping between the general-purpose registers in `struct user'
+   format and GDB's register array layout.  */
+static /*const*/ int i386_regmap[] = 
+{
+  EAX * 4, ECX * 4, EDX * 4, EBX * 4,
+  UESP * 4, EBP * 4, ESI * 4, EDI * 4,
+  EIP * 4, EFL * 4, CS * 4, SS * 4,
+  DS * 4, ES * 4, FS * 4, GS * 4
+};
+
+#define I386_NUM_REGS (sizeof (i386_regmap) / sizeof (i386_regmap[0]))
+
+#endif
+\f
+/* Called by libthread_db.  */
+
+ps_err_e
+ps_get_thread_area (const struct ps_prochandle *ph,
+		    lwpid_t lwpid, int idx, void **base)
+{
+#ifdef __x86_64__
+  int use_64bit = register_size (0) == 8;
+
+  if (use_64bit)
+    {
+      switch (idx)
+	{
+	case FS:
+	  if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0)
+	    return PS_OK;
+	  break;
+	case GS:
+	  if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0)
+	    return PS_OK;
+	  break;
+	default:
+	  return PS_BADADDR;
+	}
+      return PS_ERR;
+    }
+#endif
+
+  {
+    unsigned int desc[4];
+
+    if (ptrace (PTRACE_GET_THREAD_AREA, lwpid,
+		(void *) (intptr_t) idx, (unsigned long) &desc) < 0)
+      return PS_ERR;
+
+    *(int *)base = desc[1];
+    return PS_OK;
+  }
+}
+\f
+static int
+i386_cannot_store_register (int regno)
+{
+  return regno >= I386_NUM_REGS;
+}
+
+static int
+i386_cannot_fetch_register (int regno)
+{
+  return regno >= I386_NUM_REGS;
+}
+
+static void
+x86_fill_gregset (void *buf)
+{
+  int i;
+
+#ifdef __x86_64__
+  if (register_size (0) == 8)
+    {
+      for (i = 0; i < X86_64_NUM_REGS; i++)
+	if (x86_64_regmap[i] != -1)
+	  collect_register (i, ((char *) buf) + x86_64_regmap[i]);
+      return;
+    }
+#endif
+
+  for (i = 0; i < I386_NUM_REGS; i++)
+    collect_register (i, ((char *) buf) + i386_regmap[i]);
+
+  collect_register_by_name ("orig_eax", ((char *) buf) + ORIG_EAX * 4);
+}
+
+static void
+x86_store_gregset (const void *buf)
+{
+  int i;
+
+#ifdef __x86_64__
+  if (register_size (0) == 8)
+    {
+      for (i = 0; i < X86_64_NUM_REGS; i++)
+	if (x86_64_regmap[i] != -1)
+	  supply_register (i, ((char *) buf) + x86_64_regmap[i]);
+      return;
+    }
+#endif
+
+  for (i = 0; i < I386_NUM_REGS; i++)
+    supply_register (i, ((char *) buf) + i386_regmap[i]);
+
+  supply_register_by_name ("orig_eax", ((char *) buf) + ORIG_EAX * 4);
+}
+
+static void
+x86_fill_fpregset (void *buf)
+{
+#ifdef __x86_64__
+  i387_cache_to_fxsave (buf);
+#else
+  i387_cache_to_fsave (buf);
+#endif
+}
+
+static void
+x86_store_fpregset (const void *buf)
+{
+#ifdef __x86_64__
+  i387_fxsave_to_cache (buf);
+#else
+  i387_fsave_to_cache (buf);
+#endif
+}
+
+#ifndef __x86_64__
+
+static void
+x86_fill_fpxregset (void *buf)
+{
+  i387_cache_to_fxsave (buf);
+}
+
+static void
+x86_store_fpxregset (const void *buf)
+{
+  i387_fxsave_to_cache (buf);
+}
+
+#endif
+
+/* ??? The non-biarch i386 case stores all the i387 regs twice.
+   Once in i387_.*fsave.* and once in i387_.*fxsave.*.
+   This is, presumably, to handle the case where PTRACE_[GS]ETFPXREGS
+   doesn't work.  IWBN to avoid the duplication in the case where it
+   does work.  Maybe the arch_setup routine could check whether it works
+   and update target_regsets accordingly, maybe by moving target_regsets
+   to linux_target_ops and set the right one there, rather than having to
+   modify the target_regsets global.  */
+
+struct regset_info target_regsets[] =
+{
+#ifdef HAVE_PTRACE_GETREGS
+  { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t),
+    GENERAL_REGS,
+    x86_fill_gregset, x86_store_gregset },
+# ifndef __x86_64__
+#  ifdef HAVE_PTRACE_GETFPXREGS
+  { PTRACE_GETFPXREGS, PTRACE_SETFPXREGS, sizeof (elf_fpxregset_t),
+    EXTENDED_REGS,
+    x86_fill_fpxregset, x86_store_fpxregset },
+#  endif
+# endif
+  { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof (elf_fpregset_t),
+    FP_REGS,
+    x86_fill_fpregset, x86_store_fpregset },
+#endif /* HAVE_PTRACE_GETREGS */
+  { 0, 0, -1, -1, NULL, NULL }
+};
+
+static CORE_ADDR
+x86_get_pc (void)
+{
+  int use_64bit = register_size (0) == 8;
+
+  if (use_64bit)
+    {
+      unsigned long pc;
+      collect_register_by_name ("rip", &pc);
+      return (CORE_ADDR) pc;
+    }
+  else
+    {
+      unsigned int pc;
+      collect_register_by_name ("eip", &pc);
+      return (CORE_ADDR) pc;
+    }
+}
+
+static void
+x86_set_pc (CORE_ADDR pc)
+{
+  int use_64bit = register_size (0) == 8;
+
+  if (use_64bit)
+    {
+      unsigned long newpc = pc;
+      supply_register_by_name ("rip", &newpc);
+    }
+  else
+    {
+      unsigned int newpc = pc;
+      supply_register_by_name ("eip", &newpc);
+    }
+}
+\f
+static const unsigned char x86_breakpoint[] = { 0xCC };
+#define x86_breakpoint_len 1
+
+static int
+x86_breakpoint_at (CORE_ADDR pc)
+{
+  unsigned char c;
+
+  read_inferior_memory (pc, &c, 1);
+  if (c == 0xCC)
+    return 1;
+
+  return 0;
+}
+\f
+/* When GDBSERVER is built as a 64-bit application on linux, the
+   PTRACE_GETSIGINFO data is always presented in 64-bit layout.  Since
+   debugging a 32-bit inferior with a 64-bit GDBSERVER should look the same
+   as debugging it with a 32-bit GDBSERVER, we do the 32-bit <-> 64-bit
+   conversion in-place ourselves.  */
+
+/* These types below (compat_*) define a siginfo type that is layout
+   compatible with the siginfo type exported by the 32-bit userspace
+   support.  */
+
+#ifdef __x86_64__
+
+typedef int compat_int_t;
+typedef unsigned int compat_uptr_t;
+
+typedef int compat_time_t;
+typedef int compat_timer_t;
+typedef int compat_clock_t;
+
+struct compat_timeval
+{
+  compat_time_t tv_sec;
+  int tv_usec;
+};
+
+typedef union compat_sigval
+{
+  compat_int_t sival_int;
+  compat_uptr_t sival_ptr;
+} compat_sigval_t;
+
+typedef struct compat_siginfo
+{
+  int si_signo;
+  int si_errno;
+  int si_code;
+
+  union
+  {
+    int _pad[((128 / sizeof (int)) - 3)];
+
+    /* kill() */
+    struct
+    {
+      unsigned int _pid;
+      unsigned int _uid;
+    } _kill;
+
+    /* POSIX.1b timers */
+    struct
+    {
+      compat_timer_t _tid;
+      int _overrun;
+      compat_sigval_t _sigval;
+    } _timer;
+
+    /* POSIX.1b signals */
+    struct
+    {
+      unsigned int _pid;
+      unsigned int _uid;
+      compat_sigval_t _sigval;
+    } _rt;
+
+    /* SIGCHLD */
+    struct
+    {
+      unsigned int _pid;
+      unsigned int _uid;
+      int _status;
+      compat_clock_t _utime;
+      compat_clock_t _stime;
+    } _sigchld;
+
+    /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+    struct
+    {
+      unsigned int _addr;
+    } _sigfault;
+
+    /* SIGPOLL */
+    struct
+    {
+      int _band;
+      int _fd;
+    } _sigpoll;
+  } _sifields;
+} compat_siginfo_t;
+
+#define cpt_si_pid _sifields._kill._pid
+#define cpt_si_uid _sifields._kill._uid
+#define cpt_si_timerid _sifields._timer._tid
+#define cpt_si_overrun _sifields._timer._overrun
+#define cpt_si_status _sifields._sigchld._status
+#define cpt_si_utime _sifields._sigchld._utime
+#define cpt_si_stime _sifields._sigchld._stime
+#define cpt_si_ptr _sifields._rt._sigval.sival_ptr
+#define cpt_si_addr _sifields._sigfault._addr
+#define cpt_si_band _sifields._sigpoll._band
+#define cpt_si_fd _sifields._sigpoll._fd
+
+/* glibc at least up to 2.3.2 doesn't have si_timerid, si_overrun.
+   In their place is si_timer1,si_timer2.  */
+#ifndef si_timerid
+#define si_timerid si_timer1
+#endif
+#ifndef si_overrun
+#define si_overrun si_timer2
+#endif
+
+static void
+compat_siginfo_from_siginfo (compat_siginfo_t *to, siginfo_t *from)
+{
+  memset (to, 0, sizeof (*to));
+
+  to->si_signo = from->si_signo;
+  to->si_errno = from->si_errno;
+  to->si_code = from->si_code;
+
+  if (to->si_code < 0)
+    {
+      to->cpt_si_ptr = (intptr_t) from->si_ptr;
+    }
+  else if (to->si_code == SI_USER)
+    {
+      to->cpt_si_pid = from->si_pid;
+      to->cpt_si_uid = from->si_uid;
+    }
+  else if (to->si_code == SI_TIMER)
+    {
+      to->cpt_si_timerid = from->si_timerid;
+      to->cpt_si_overrun = from->si_overrun;
+      to->cpt_si_ptr = (intptr_t) from->si_ptr;
+    }
+  else
+    {
+      switch (to->si_signo)
+	{
+	case SIGCHLD:
+	  to->cpt_si_pid = from->si_pid;
+	  to->cpt_si_uid = from->si_uid;
+	  to->cpt_si_status = from->si_status;
+	  to->cpt_si_utime = from->si_utime;
+	  to->cpt_si_stime = from->si_stime;
+	  break;
+	case SIGILL:
+	case SIGFPE:
+	case SIGSEGV:
+	case SIGBUS:
+	  to->cpt_si_addr = (intptr_t) from->si_addr;
+	  break;
+	case SIGPOLL:
+	  to->cpt_si_band = from->si_band;
+	  to->cpt_si_fd = from->si_fd;
+	  break;
+	default:
+	  to->cpt_si_pid = from->si_pid;
+	  to->cpt_si_uid = from->si_uid;
+	  to->cpt_si_ptr = (intptr_t) from->si_ptr;
+	  break;
+	}
+    }
+}
+
+static void
+siginfo_from_compat_siginfo (siginfo_t *to, compat_siginfo_t *from)
+{
+  memset (to, 0, sizeof (*to));
+
+  to->si_signo = from->si_signo;
+  to->si_errno = from->si_errno;
+  to->si_code = from->si_code;
+
+  if (to->si_code < 0)
+    {
+      to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
+    }
+  else if (to->si_code == SI_USER)
+    {
+      to->si_pid = from->cpt_si_pid;
+      to->si_uid = from->cpt_si_uid;
+    }
+  else if (to->si_code == SI_TIMER)
+    {
+      to->si_timerid = from->cpt_si_timerid;
+      to->si_overrun = from->cpt_si_overrun;
+      to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
+    }
+  else
+    {
+      switch (to->si_signo)
+	{
+	case SIGCHLD:
+	  to->si_pid = from->cpt_si_pid;
+	  to->si_uid = from->cpt_si_uid;
+	  to->si_status = from->cpt_si_status;
+	  to->si_utime = from->cpt_si_utime;
+	  to->si_stime = from->cpt_si_stime;
+	  break;
+	case SIGILL:
+	case SIGFPE:
+	case SIGSEGV:
+	case SIGBUS:
+	  to->si_addr = (void *) (intptr_t) from->cpt_si_addr;
+	  break;
+	case SIGPOLL:
+	  to->si_band = from->cpt_si_band;
+	  to->si_fd = from->cpt_si_fd;
+	  break;
+	default:
+	  to->si_pid = from->cpt_si_pid;
+	  to->si_uid = from->cpt_si_uid;
+	  to->si_ptr = (void* ) (intptr_t) from->cpt_si_ptr;
+	  break;
+	}
+    }
+}
+
+#endif /* __x86_64__ */
+
+/* Convert a native/host siginfo object, into/from the siginfo in the
+   layout of the inferiors' architecture.  Returns true if any
+   conversion was done; false otherwise.  If DIRECTION is 1, then copy
+   from INF to NATIVE.  If DIRECTION is 0, copy from NATIVE to
+   INF.  */
+
+static int
+x86_siginfo_fixup (struct siginfo *native, void *inf, int direction)
+{
+#ifdef __x86_64__
+  /* Is the inferior 32-bit?  If so, then fixup the siginfo object.  */
+  if (register_size (0) == 4)
+    {
+      assert (sizeof (struct siginfo) == sizeof (compat_siginfo_t));
+
+      if (direction == 0)
+	compat_siginfo_from_siginfo ((struct compat_siginfo *) inf, native);
+      else
+	siginfo_from_compat_siginfo (native, (struct compat_siginfo *) inf);
+
+      return 1;
+    }
+#endif
+
+  return 0;
+}
+\f
+/* Return non-zero if the target is 64-bit.  */
+
+static void
+x86_arch_setup (void)
+{
+#ifdef __x86_64__
+  int pid = pid_of (get_thread_lwp (current_inferior));
+  char *file = linux_child_pid_to_exec_file (pid);
+  int use_64bit = elf_64_file_p (file);
+
+  free (file);
+
+  if (use_64bit < 0)
+    {
+      /* This can only happen if /proc/<pid>/exe is unreadable,
+	 but "that can't happen" if we've gotten this far.
+	 Fall through and assume this is a 32-bit program.  */
+    }
+  else if (use_64bit)
+    {
+      init_registers_x86_64_linux ();
+
+      /* Amd64 doesn't have HAVE_LINUX_USRREGS.  */
+      the_low_target.num_regs = -1;
+      the_low_target.regmap = NULL;
+      the_low_target.cannot_fetch_register = NULL;
+      the_low_target.cannot_store_register = NULL;
+
+      /* Amd64 has 16 xmm regs.  */
+      num_xmm_registers = 16;
+
+      return;
+    }
+#endif
+
+  /* Ok we have a 32-bit inferior.  */
+
+  init_registers_i386_linux ();
+
+  the_low_target.num_regs = I386_NUM_REGS;
+  the_low_target.regmap = i386_regmap;
+  the_low_target.cannot_fetch_register = i386_cannot_fetch_register;
+  the_low_target.cannot_store_register = i386_cannot_store_register;
+
+  /* I386 has 8 xmm regs.  */
+  num_xmm_registers = 8;
+}
+
+/* This is initialized assuming an amd64 target.
+   x86_arch_setup will correct it for i386 or amd64 targets.  */
+
+struct linux_target_ops the_low_target =
+{
+  x86_arch_setup,
+  -1,
+  NULL,
+  NULL,
+  NULL,
+  x86_get_pc,
+  x86_set_pc,
+  x86_breakpoint,
+  x86_breakpoint_len,
+  NULL,
+  1,
+  x86_breakpoint_at,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  /* collect_ptrace_register/supply_ptrace_register are not needed in the
+     native i386 case (no registers smaller than an xfer unit), and are not
+     used in the biarch case (HAVE_LINUX_USRREGS is not defined).  */
+  NULL,
+  NULL,
+  /* need to fix up i386 siginfo if host is amd64 */
+  x86_siginfo_fixup,
+};


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

* Re: [RFC] i386/amd64 biarch gdbserver
  2009-05-09 19:12 [RFC] i386/amd64 biarch gdbserver Doug Evans
@ 2009-05-11 17:50 ` Pedro Alves
  2009-05-11 19:16   ` Joel Brobecker
  0 siblings, 1 reply; 4+ messages in thread
From: Pedro Alves @ 2009-05-11 17:50 UTC (permalink / raw)
  To: gdb-patches; +Cc: Doug Evans

On Saturday 09 May 2009 20:12:25, Doug Evans wrote:

> This patch implements biarch i386/amd64 gdbserver.

> I haven't done anything with xml target descriptions, but there
> are no regressions so it seems like a good stopping place.

Yeah, this came up on IRC, when I mentioned about gdbserver
multi-process, and debugging 32-bit and 64-bit inferiors
simultaneously.  The x86 and amd64 register sets aren't compatible,
and, we've got a single target_gdbarch to represent the connection, so
this is a problem.  But it's one we can solve on top of this.

> This patch also fixes a bug where current amd64 gdbserver
> doesn't handle xmm[8-15].  Testcase to follow later.
> 
> Tested on
> - i386-linux
> - x86_64-linux with gcc -m64
> - x86_64-linux with gcc -m32 (and hacking site.exp to specify i386-linux)
> using --target_board=native-gdbserver
> [ref http://sourceware.org/gdb/wiki/Native_gdbserver_testing]
> 
> Comments?

This looks good to me, but, I don't know how far can I stretch in
gdbserver approvals.

Small nit, you've added an `assert' call, but I think you should use `fatal'
instead -- there are no other references to `assert' in gdbserver whole.

> +/* Return non-zero if the target is 64-bit.  */
> +
> +static void
> +x86_arch_setup (void)

Misplaced comment?

-- 
Pedro Alves


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

* Re: [RFC] i386/amd64 biarch gdbserver
  2009-05-11 17:50 ` Pedro Alves
@ 2009-05-11 19:16   ` Joel Brobecker
  2009-05-11 21:18     ` Pedro Alves
  0 siblings, 1 reply; 4+ messages in thread
From: Joel Brobecker @ 2009-05-11 19:16 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches, Doug Evans

> This looks good to me, but, I don't know how far can I stretch in
> gdbserver approvals.

As far as I can tell, there are not that many active maintainers
that work on gdbserver. It used to be mostly Daniel who approved
patches. You're responsible for most of the changes this year,
so I would personally say that you're one of the most qualified.

-- 
Joel


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

* Re: [RFC] i386/amd64 biarch gdbserver
  2009-05-11 19:16   ` Joel Brobecker
@ 2009-05-11 21:18     ` Pedro Alves
  0 siblings, 0 replies; 4+ messages in thread
From: Pedro Alves @ 2009-05-11 21:18 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: gdb-patches, Doug Evans

On Monday 11 May 2009 20:16:42, Joel Brobecker wrote:
> > This looks good to me, but, I don't know how far can I stretch in
> > gdbserver approvals.
> 
> As far as I can tell, there are not that many active maintainers
> that work on gdbserver. It used to be mostly Daniel who approved
> patches. You're responsible for most of the changes this year,
> so I would personally say that you're one of the most qualified.

Thanks, though I'm not sure if that's such a good thing :-).

Doug, please go ahead with your patch.  Everyone else, please feel
free to hit me over head with a cluebat on proper ocasions.

-- 
Pedro Alves


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

end of thread, other threads:[~2009-05-11 21:18 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-05-09 19:12 [RFC] i386/amd64 biarch gdbserver Doug Evans
2009-05-11 17:50 ` Pedro Alves
2009-05-11 19:16   ` Joel Brobecker
2009-05-11 21:18     ` Pedro Alves

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