bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 1/2] Port gdbserver to GNU/Hurd


From: Yue Lu
Subject: Re: [PATCH 1/2] Port gdbserver to GNU/Hurd
Date: Thu, 5 Sep 2013 18:53:37 +0800

Hi,

This is the my new patch.

On Tue, Sep 3, 2013 at 7:11 PM, Pedro Alves <address@hidden> wrote:
> So my idea would be, instead of adding the new files under gdbserver,
> to remove the spurious differences (formatting, reordering, etc.) that
> were introduced in the gdbserver copies of the files, eliminating the
> unnecessary divergence, and then fold back the resulting differences into
> the original gdb/gnu-nat.c etc. files, guarded by #ifdef GDBSERVER.  Some
> cleanups might have been identified and done in the gdbserver files, and
> it might make sense to do those as preparatory work, in the original files.
> This should result in smaller patches, and will actually avoid
> the need for most of the polishing Thomas mentioned, and as consequence
> review burden -- reviewing the new gnu-low.c etc., for GNU conventions,
> formatting, or even appropriate use of the Hurd's debug APIs etc., is
> just unnecessary that way, by design, and we'll be able to focus on the
> bits that are the real new code -- the glue between the target and gdb, and
> the target and gdbserver.

I have put some soft link in directory gdbserver like *.defs which
point to [gdb]/gdb/*.defs.
2013-09-03  Yue Lu  <address@hidden>
gdb
        * configure.tgt: Set build_gdbserver=yes for GNU/Hurd hosts.
        * configure: Regenerate.
        * config/i386/i386gnu.mh: Add #ifdef to determine which rule
to use in gdbserver.
        * i386gnu-nat.c: Add macor GDBSERVER to support build gdbserver.
        * gnu-nat.h: Add macor GDBSERVER to support build gdbserver.
        * gnu-nat.c: Add macor GDBSERVER to support build gdbserver.
        (gnu_debug): New function, use for debug printf.
        (gnu_wait_1): wait for inferior used in gdbserver.
        (gnu_resume_1): resume inferior used in gdbserver.
        (gnu_kill): New function, used in gdbserver.
        (gnu_mourn): New function, clean up after inferior dies, used
in gdbserver.
        (gnu_create_inferior): New function, use for create inferior
in gdbserver.
        (gnu_attach): New function, a placeholder.
        (gnu_detach): New function, used in gdbserver detach from inferior.
        (gnu_thread_alive): New function, call find_thread_ptid().
        (gnu_ptid_build): New function, build structure ptid_t from
pid, and tid.
        (gnu_get_tid): New function, return lwp from structure ptid_t,
this is different with gdb's behavior.
        (gnu_add_process): New function, add a new process to process list.
        (gnu_join): New function, a placeholder.
        (gnu_resume): New function, a wrap function, just call gnu_resume_1().
        (gnu_wait): New function, a wrap function, just call gnu_wait_1().
        (gnu_fetch_registers_wrap): New function, a wrap function,
just call gnu_fetch_registers().
        (gnu_store_registers_wrap): New function, a wrap function,
just call gnu_store_registers().
        (gnu_read_memory): New function, a wrap function, just call
gnu_read_inferior().
        (gnu_write_memory): New function, a wrap function, just call
gnu_write_inferior().
        (gnu_request_interrupt): New function, a placeholder.
        (store_waitstatus): New function, helper function, copy from
[gdb]/gdb/inf-child.c.
        (initialize_low): New function, use for initialize gdbserver's
target_ops.
        (initialize_low_arch): New function, used by initialize_low().
        (_initialize_gnu_nat): New function, used by initialize_low().

diff --git a/gdb/config/i386/i386gnu.mh b/gdb/config/i386/i386gnu.mh
index a3ea122..224cf0f 100644
--- a/gdb/config/i386/i386gnu.mh
+++ b/gdb/config/i386/i386gnu.mh
@@ -1,4 +1,5 @@
 # Host: Intel 386 running the GNU Hurd
+ifndef GDBSERVER
 NATDEPFILES= i386gnu-nat.o gnu-nat.o core-regset.o fork-child.o \
      notify_S.o process_reply_S.o msg_reply_S.o \
      msg_U.o exc_request_U.o exc_request_S.o
@@ -12,6 +13,10 @@ XM_CLIBS = -lshouldbeinlibc
 # Use our own user stubs for the msg rpcs, so we can make them time out, in
 # case the program is fucked, or we guess the wrong signal thread.
 msg-MIGUFLAGS = -D'MSG_IMPORTS=waittime 1000;'
+else
+NATDEPFILES= notify_S.o process_reply_S.o msg_reply_S.o \
+      exc_request_U.o exc_request_S.o
+endif

 # ick
 MIGCOM = $(MIG) -cc cat - /dev/null
diff --git a/gdb/configure.tgt b/gdb/configure.tgt
index b0bee47..3eb2ff7 100644
--- a/gdb/configure.tgt
+++ b/gdb/configure.tgt
@@ -231,6 +231,7 @@ i[34567]86-*-linux*)
 i[34567]86-*-gnu*)
  # Target: Intel 386 running the GNU Hurd
  gdb_target_obs="i386-tdep.o i387-tdep.o i386gnu-tdep.o solib-svr4.o"
+ build_gdbserver=yes
  ;;
 i[34567]86-*-cygwin*)
  # Target: Intel 386 running win32
diff --git a/gdb/gnu-nat.c b/gdb/gnu-nat.c
index 59d2f23..1cdcd1d 100644
--- a/gdb/gnu-nat.c
+++ b/gdb/gnu-nat.c
@@ -1,6 +1,7 @@
 /* Interface GDB to the GNU Hurd.
    Copyright (C) 1992-2013 Free Software Foundation, Inc.

+
    This file is part of GDB.

    Written by Miles Bader <address@hidden>
@@ -20,6 +21,7 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

+#ifndef GDBSERVER
 #include "defs.h"

 #include <ctype.h>
@@ -31,18 +33,6 @@
 #include "gdb_string.h"
 #include <sys/ptrace.h>

-#include <mach.h>
-#include <mach_error.h>
-#include <mach/exception.h>
-#include <mach/message.h>
-#include <mach/notify.h>
-#include <mach/vm_attributes.h>
-
-#include <hurd.h>
-#include <hurd/interrupt.h>
-#include <hurd/msg.h>
-#include <hurd/msg_request.h>
-#include <hurd/process.h>
 /* Defined in <hurd/process.h>, but we need forward declarations from
    <hurd/process_request.h> as well.  */
 #undef _process_user_
@@ -64,17 +54,55 @@
 #include "gdb_assert.h"
 #include "gdb_obstack.h"

-#include "gnu-nat.h"
 #include "inf-child.h"

+#include "exc_request_U.h"
+#include "msg_U.h"
+
+#else /* GDBSERVER */
+#include "server.h"
+#include "target.h"
+
+#include <limits.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include "gdb_wait.h"
+#include <signal.h>
+#include <sys/ptrace.h>
+#endif /* GDBSERVER */
+
+#include <mach.h>
+#include <mach_error.h>
+#include <mach/exception.h>
+#include <mach/message.h>
+
+#include <mach/notify.h>
+#include <mach/vm_attributes.h>
+
+#include <hurd.h>
+#include <hurd/interrupt.h>
+#include <hurd/msg.h>
+#include <hurd/msg_request.h>
+#include <hurd/process.h>
+
+#include "gnu-nat.h"
 #include "exc_request_S.h"
 #include "notify_S.h"
 #include "process_reply_S.h"
 #include "msg_reply_S.h"
-#include "exc_request_U.h"
-#include "msg_U.h"

 static process_t proc_server = MACH_PORT_NULL;
+#ifdef GDBSERVER
+/* this should move into gnu-i386-low.c ?*/
+/* Defined in auto-generated file i386.c.  */
+extern void init_registers_i386 (void);
+extern const struct target_desc *tdesc_i386;
+const struct target_desc *gnu_tdesc;
+int using_threads = 1;
+ptid_t inferior_ptid;
+static struct target_ops gnu_target_ops;
+#endif

 /* If we've sent a proc_wait_request to the proc server, the pid of the
    process we asked about.  We can only ever have one outstanding.  */
@@ -114,6 +142,12 @@ void inf_continue (struct inf *inf);
        debug ("{inf %d %s}: " msg, __inf->pid, \
        host_address_to_string (__inf) , ##args); } while (0)

+#ifdef GDBSERVER
+static ptid_t gnu_ptid_build (int pid, long lwp, long tid);
+static long gnu_get_tid (ptid_t ptid);
+static struct process_info * gnu_add_process (int pid, int attached);
+#endif
+
 void proc_abort (struct proc *proc, int force);
 struct proc *make_proc (struct inf *inf, mach_port_t port, int tid);
 struct proc *_proc_free (struct proc *proc);
@@ -145,7 +179,27 @@ int proc_trace (struct proc *proc, int set);
  __e; }) \
    : EIEIO)

-
+#ifdef GDBSERVER
+struct process_info_private
+{
+  struct inf *inf;
+};
+
+void
+gnu_debug (char *string, ...)
+{
+  va_list args;
+
+  if (!gnu_debug_flag)
+    return;
+  va_start (args, string);
+  fprintf (stderr, "DEBUG(gnu): ");
+  vfprintf (stderr, string, args);
+  fprintf (stderr, "\n");
+  va_end (args);
+}
+#endif
+
 /* The state passed by an exception message.  */
 struct exc_state
   {
@@ -242,14 +296,12 @@ struct inf
     int want_exceptions;
   };

-
 int
 __proc_pid (struct proc *proc)
 {
   return proc->inf->pid;
 }

-
 /* Update PROC's real suspend count to match it's desired one.  Returns true
    if we think PROC is now in a runnable state.  */
 int
@@ -313,7 +365,6 @@ proc_update_sc (struct proc *proc)
   return running;
 }

-
 /* Thread_abort is called on PROC if needed.  PROC must be a thread proc.
    If PROC is deemed `precious', then nothing is done unless FORCE is true.
    In particular, a thread is precious if it's running (in which case forcing
@@ -390,7 +441,6 @@ proc_get_state (struct proc *proc, int will_modify)
     return 0;
 }

-
 /* Set PORT to PROC's exception port.  */
 error_t
 proc_get_exception_port (struct proc * proc, mach_port_t * port)
@@ -506,7 +556,6 @@ proc_restore_exc_port (struct proc *proc)
     }
 }

-
 /* Turns hardware tracing in PROC on or off when SET is true or false,
    respectively.  Returns true on success.  */
 int
@@ -533,7 +582,6 @@ proc_trace (struct proc *proc, int set)
   return 1;
 }

-
 /* A variable from which to assign new TIDs.  */
 static int next_thread_id = 1;

@@ -610,7 +658,6 @@ _proc_free (struct proc *proc)
   struct proc *next = proc->next;

   proc_debug (proc, "freeing...");
-
   if (proc == inf->step_thread)
     /* Turn off single stepping.  */
     inf_set_step_thread (inf, 0);
@@ -637,7 +684,6 @@ _proc_free (struct proc *proc)
   return next;
 }

-
 struct inf *
 make_inf (void)
 {
@@ -691,7 +737,6 @@ inf_clear_wait (struct inf *inf)
     }
 }

-
 void
 inf_cleanup (struct inf *inf)
 {
@@ -736,7 +781,6 @@ inf_startup (struct inf *inf, int pid)
   inf_set_pid (inf, pid);
 }

-
 /* Close current process, if any, and attach INF to process PORT.  */
 void
 inf_set_pid (struct inf *inf, pid_t pid)
@@ -786,7 +830,6 @@ inf_set_pid (struct inf *inf, pid_t pid)
     inf->pid = -1;
 }

-
 /* Validates INF's stopped, nomsg and traced field from the actual
    proc server state.  Note that the traced field is only updated from
    the proc server state if we do not have a message port.  If we do
@@ -855,6 +898,7 @@ inf_validate_task_sc (struct inf *inf)

   if (inf->task->cur_sc < suspend_count)
     {
+#ifndef GDBSERVER
       int abort;

       target_terminal_ours (); /* Allow I/O.  */
@@ -865,7 +909,9 @@ inf_validate_task_sc (struct inf *inf)

       if (abort)
  error (_("Additional task suspend count left untouched."));
+#endif

+      //need fix!
       inf->task->cur_sc = suspend_count;
     }
 }
@@ -905,7 +951,6 @@ inf_set_traced (struct inf *inf, int on)
     inf->traced = on;
 }

-
 /* Makes all the real suspend count deltas of all the procs in INF
    match the desired values.  Careful to always do thread/task suspend
    counts in the safe order.  Returns true if at least one thread is
@@ -959,7 +1004,6 @@ inf_update_suspends (struct inf *inf)
   return 0;
 }

-
 /* Converts a GDB pid to a struct proc.  */
 struct proc *
 inf_tid_to_thread (struct inf *inf, int tid)
@@ -988,7 +1032,6 @@ inf_port_to_thread (struct inf *inf, mach_port_t port)
   return 0;
 }

-
 /* Make INF's list of threads be consistent with reality of TASK.  */
 void
 inf_validate_procs (struct inf *inf)
@@ -1056,6 +1099,12 @@ inf_validate_procs (struct inf *inf)
  if (!left)
   {
     proc_debug (thread, "died!");
+#ifdef GDBSERVER
+    ptid_t ptid;
+    ptid = gnu_ptid_build (inf->pid, 0, thread->tid);
+    if (find_thread_ptid (ptid))
+      remove_thread (find_thread_ptid (ptid));
+#endif
     thread->port = MACH_PORT_NULL;
     thread = _proc_free (thread); /* THREAD is dead.  */
     if (last)
@@ -1083,10 +1132,15 @@ inf_validate_procs (struct inf *inf)
     last = thread;
     proc_debug (thread, "new thread: %d", threads[i]);

+#ifndef GDBSERVER
     ptid = ptid_build (inf->pid, 0, thread->tid);
+#else
+    ptid = gnu_ptid_build (inf->pid, 0, thread->tid);
+#endif

     /* Tell GDB's generic thread code.  */

+#ifndef GDBSERVER
     if (ptid_equal (inferior_ptid, pid_to_ptid (inf->pid)))
       /* This is the first time we're hearing about thread
  ids, after a fork-child.  */
@@ -1096,6 +1150,15 @@ inf_validate_procs (struct inf *inf)
       add_thread_silent (ptid);
     else
       add_thread (ptid);
+#else
+    if (!find_thread_ptid (ptid))
+      {
+ gnu_debug ("New thread, pid=%d, tid=%d\n", inf->pid,
+   thread->tid);
+ add_thread (ptid, thread);
+ inferior_ptid = ptid; // need fix!!!!!!!!!!!!!
+      }
+#endif
   }
       }

@@ -1104,7 +1167,6 @@ inf_validate_procs (struct inf *inf)
   }
 }

-
 /* Makes sure that INF's thread list is synced with the actual process.  */
 int
 inf_update_procs (struct inf *inf)
@@ -1135,7 +1197,6 @@ inf_set_threads_resume_sc (struct inf *inf,
       thread->resume_sc = thread->pause_sc;
 }

-
 /* Cause INF to continue execution immediately; individual threads may still
    be suspended (but their suspend counts will be updated).  */
 void
@@ -1179,7 +1240,6 @@ inf_suspend (struct inf *inf)
   inf_update_suspends (inf);
 }

-
 /* INF has one thread PROC that is in single-stepping mode.  This
    function changes it to be PROC, changing any old step_thread to be
    a normal one.  A PROC of 0 clears any existing value.  */
@@ -1205,7 +1265,6 @@ inf_set_step_thread (struct inf *inf, struct proc *thread)
     }
 }

-
 /* Set up the thread resume_sc's so that only the signal thread is running
    (plus whatever other thread are set to always run).  Returns true if we
    did so, or false if we can't find a signal thread.  */
@@ -1221,6 +1280,7 @@ inf_set_threads_resume_sc_for_signal_thread
(struct inf *inf)
     return 0;
 }

+#ifndef GDBSERVER
 static void
 inf_update_signal_thread (struct inf *inf)
 {
@@ -1229,7 +1289,7 @@ inf_update_signal_thread (struct inf *inf)
   inf->signal_thread = inf->threads ? inf->threads->next : 0;
 }

-
+#endif
 /* Detachs from INF's inferior task, letting it run once again...  */
 void
 inf_detach (struct inf *inf)
@@ -1284,7 +1344,7 @@ inf_attach (struct inf *inf, int pid)
   inf_startup (inf, pid);
 }

-
+#ifndef GDBSERVER
 /* Makes sure that we've got our exception ports entrenched in the process.  */
 void
 inf_steal_exc_ports (struct inf *inf)
@@ -1314,8 +1374,8 @@ inf_restore_exc_ports (struct inf *inf)
   for (thread = inf->threads; thread; thread = thread->next)
     proc_restore_exc_port (thread);
 }
+#endif

-
 /* Deliver signal SIG to INF.  If INF is stopped, delivering a signal, even
    signal 0, will continue it.  INF is assumed to be in a paused state, and
    the resume_sc's of INF's threads may be affected.  */
@@ -1404,7 +1464,6 @@ inf_signal (struct inf *inf, enum gdb_signal sig)
 #undef NAME
 }

-
 /* Continue INF without delivering a signal.  This is meant to be used
    when INF does not have a message port.  */
 void
@@ -1433,7 +1492,6 @@ inf_continue (struct inf *inf)
     warning (_("Can't continue process: %s"), safe_strerror (err));
 }

-
 /* The inferior used for all gdb target ops.  */
 struct inf *gnu_current_inf = 0;

@@ -1443,8 +1501,13 @@ struct inf *waiting_inf;

 /* Wait for something to happen in the inferior, returning what in STATUS.  */
 static ptid_t
+#ifdef GDBSERVER
+gnu_wait_1 (ptid_t ptid, struct target_waitstatus *status,
+    int target_options)
+#else
 gnu_wait (struct target_ops *ops,
   ptid_t ptid, struct target_waitstatus *status, int options)
+#endif
 {
   struct msg
     {
@@ -1613,19 +1676,29 @@ rewait:

   thread = inf->wait.thread;
   if (thread)
+#ifndef GDBSERVER
     ptid = ptid_build (inf->pid, 0, thread->tid);
+#else
+    ptid = gnu_ptid_build (inf->pid, 0, thread->tid);
+#endif
   else if (ptid_equal (ptid, minus_one_ptid))
     thread = inf_tid_to_thread (inf, -1);
   else
+#ifndef GDBSERVER
     thread = inf_tid_to_thread (inf, ptid_get_tid (ptid));
+#else
+    thread = inf_tid_to_thread (inf, gnu_get_tid (ptid));
+#endif

   if (!thread || thread->port == MACH_PORT_NULL)
     {
       /* TID is dead; try and find a new thread.  */
       if (inf_update_procs (inf) && inf->threads)
- ptid = ptid_build (inf->pid, 0, inf->threads->tid); /* The first
-       available
-       thread.  */
+#ifndef GDBSERVER
+ ptid = ptid_build (inf->pid, 0, inf->threads->tid);
+#else
+ ptid = gnu_ptid_build (inf->pid, 0, inf->threads->tid);
+#endif /* The first available thread*/
       else
  ptid = inferior_ptid; /* let wait_for_inferior handle exit case */
     }
@@ -1651,10 +1724,12 @@ rewait:
      : "?",
      status->value.integer);

+#ifdef GDBSERVER
+  inferior_ptid = ptid;
+#endif
   return ptid;
 }

-
 /* The rpc handler called by exc_server.  */
 error_t
 S_exception_raise_request (mach_port_t port, mach_port_t reply_port,
@@ -1736,11 +1811,9 @@ S_exception_raise_request (mach_port_t port,
mach_port_t reply_port,
       inf->wait.suppress = 1;
       mach_port_deallocate (mach_task_self (), reply_port);
     }
-
   return 0;
 }

-
 /* Fill in INF's wait field after a task has died without giving us more
    detailed information.  */
 void
@@ -1794,7 +1867,6 @@ do_mach_notify_dead_name (mach_port_t notify,
mach_port_t dead_port)
   return 0;
 }

-
 static error_t
 ill_rpc (char *fun)
 {
@@ -1832,7 +1904,6 @@ do_mach_notify_send_once (mach_port_t notify)
   return ill_rpc ("do_mach_notify_send_once");
 }

-
 /* Process_reply server routines.  We only use process_wait_reply.  */

 error_t
@@ -1901,7 +1972,6 @@ S_proc_getmsgport_reply (mach_port_t reply,
error_t err, mach_port_t msg_port)
   return ill_rpc ("S_proc_getmsgport_reply");
 }

-
 /* Msg_reply server routines.  We only use msg_sig_post_untraced_reply.  */

 error_t
@@ -1930,7 +2000,6 @@ S_msg_sig_post_untraced_reply (mach_port_t
reply, error_t err)
     inf->stopped = 1;
   else
     inf->wait.suppress = 1;
-
   return 0;
 }

@@ -1940,7 +2009,6 @@ S_msg_sig_post_reply (mach_port_t reply, error_t err)
   return ill_rpc ("S_msg_sig_post_reply");
 }

-
 /* Returns the number of messages queued for the receive right PORT.  */
 static mach_port_msgcount_t
 port_msgs_queued (mach_port_t port)
@@ -1955,7 +2023,6 @@ port_msgs_queued (mach_port_t port)
     return status.mps_msgcount;
 }

-
 /* Resume execution of the inferior process.

    If STEP is nonzero, single-step it.
@@ -1973,8 +2040,13 @@ port_msgs_queued (mach_port_t port)
    in multiple events returned by wait).  */

 static void
+#ifndef GDBSERVER
 gnu_resume (struct target_ops *ops,
     ptid_t ptid, int step, enum gdb_signal sig)
+#else
+gnu_resume_1 (struct target_ops *ops,
+      ptid_t ptid, int step, enum gdb_signal sig)
+#endif
 {
   struct proc *step_thread = 0;
   int resume_all;
@@ -1997,9 +2069,11 @@ gnu_resume (struct target_ops *ops,
        abort the faulting thread, which will perhaps retake it.  */
     {
       proc_abort (inf->wait.thread, 1);
+#ifndef GDBSERVER
       warning (_("Aborting %s with unforwarded exception %s."),
        proc_string (inf->wait.thread),
        gdb_signal_to_name (inf->wait.status.value.sig));
+#endif
     }

   if (port_msgs_queued (inf->event_port))
@@ -2022,7 +2096,12 @@ gnu_resume (struct target_ops *ops,
   else
     /* Just allow a single thread to run.  */
     {
+#ifdef GDBSERVER
+      struct proc *thread = inf_tid_to_thread (inf, gnu_get_tid (ptid));
+#else
       struct proc *thread = inf_tid_to_thread (inf, ptid_get_tid (ptid));
+#endif
+

       if (!thread)
  error (_("Can't run single thread id %s: no such thread!"),
@@ -2033,7 +2112,12 @@ gnu_resume (struct target_ops *ops,

   if (step)
     {
+#ifdef GDBSERVER
+      step_thread = inf_tid_to_thread (inf, gnu_get_tid (ptid));
+#else
       step_thread = inf_tid_to_thread (inf, ptid_get_tid (ptid));
+#endif
+
       if (!step_thread)
  warning (_("Can't step thread id %s: no such thread."),
  target_pid_to_str (ptid));
@@ -2047,7 +2131,7 @@ gnu_resume (struct target_ops *ops,
   inf_resume (inf);
 }

-
+#ifndef GDBSERVER
 static void
 gnu_kill_inferior (struct target_ops *ops)
 {
@@ -2061,8 +2145,29 @@ gnu_kill_inferior (struct target_ops *ops)
     }
   target_mourn_inferior ();
 }
+#else
+static int
+gnu_kill (int pid)
+{
+  struct proc *task = gnu_current_inf->task;
+  struct process_info *process;
+
+  process = find_process_pid (pid);
+
+  if (task)
+    {
+      proc_debug (task, "terminating...");
+      task_terminate (task->port);
+      inf_set_pid (gnu_current_inf, -1);
+    }
+  the_target->mourn (process);
+  return 0;
+}
+#endif
+

 /* Clean up after the inferior dies.  */
+#ifndef GDBSERVER
 static void
 gnu_mourn_inferior (struct target_ops *ops)
 {
@@ -2071,8 +2176,18 @@ gnu_mourn_inferior (struct target_ops *ops)
   unpush_target (ops);
   generic_mourn_inferior ();
 }
+#else
+static void
+gnu_mourn (struct process_info *process)
+{
+  /* Free our private data.  */
+  free (process->private);
+  process->private = NULL;
+
+  clear_inferiors ();
+}
+#endif

-
 /* Fork an inferior process, and start debugging it.  */

 /* Set INFERIOR_PID to the first thread available in the child, if any.  */
@@ -2095,6 +2210,7 @@ cur_inf (void)
   return gnu_current_inf;
 }

+#ifndef GDBSERVER
 static void
 gnu_create_inferior (struct target_ops *ops,
      char *exec_file, char *allargs, char **env,
@@ -2148,10 +2264,34 @@ gnu_create_inferior (struct target_ops *ops,
   else
     inf_restore_exc_ports (inf);
 }
+#else
+static int
+gnu_create_inferior (char *program, char **allargs)
+{
+  int pid;
+  pid = fork ();
+  if (pid < 0)
+    perror_with_name ("fork");
+
+  if (pid == 0)
+    {
+      ptrace (PTRACE_TRACEME);
+      setpgid (0, 0);
+      execv (program, allargs);
+
+      fprintf (stderr, "Cannot exec %s: %s.\n", program, strerror (errno));
+      fflush (stderr);
+      _exit (0177);
+    }
+
+  gnu_add_process (pid, 0);
+  return pid;
+}
+#endif

-
 /* Attach to process PID, then initialize for debugging it
    and wait for the trace-trap that results from attaching.  */
+#ifndef GDBSERVER
 static void
 gnu_attach (struct target_ops *ops, char *args, int from_tty)
 {
@@ -2207,8 +2347,14 @@ gnu_attach (struct target_ops *ops, char *args,
int from_tty)
   renumber_threads (0); /* Give our threads reasonable names.  */
 #endif
 }
+#else
+static int
+gnu_attach (unsigned long pid)
+{
+  return -1; //not support now
+}
+#endif

-
 /* Take a program previously attached to and detaches it.
    The program resumes execution and will no longer stop
    on signals, etc.  We'd better not have left any breakpoints
@@ -2216,6 +2362,7 @@ gnu_attach (struct target_ops *ops, char *args,
int from_tty)
    to work, it may be necessary for the process to have been
    previously attached.  It *might* work if the program was
    started via fork.  */
+#ifndef GDBSERVER
 static void
 gnu_detach (struct target_ops *ops, char *args, int from_tty)
 {
@@ -2255,7 +2402,25 @@ gnu_stop (ptid_t ptid)
 {
   error (_("to_stop target function not implemented"));
 }
+#else
+static int
+gnu_detach (int pid)
+{
+  struct process_info *process;
+
+  process = find_process_pid (pid);
+  if (process == NULL)
+    return -1;
+
+  inf_detach (gnu_current_inf);

+  inferior_ptid = null_ptid;
+  the_target->mourn (process);
+  return 0;
+}
+#endif
+
+#ifndef GDBSERVER
 static int
 gnu_thread_alive (struct target_ops *ops, ptid_t ptid)
 {
@@ -2263,8 +2428,15 @@ gnu_thread_alive (struct target_ops *ops, ptid_t ptid)
   return !!inf_tid_to_thread (gnu_current_inf,
       ptid_get_tid (ptid));
 }
+#else
+static int
+gnu_thread_alive (ptid_t ptid)
+{
+  /* this function is copyed from lynx-low.c */
+  return (find_thread_ptid (ptid) != NULL);
+}
+#endif

-
 /* Read inferior task's LEN bytes from ADDR and copy it to MYADDR in
    gdb's address space.  Return 0 on failure; number of bytes read
    otherwise.  */
@@ -2310,7 +2482,9 @@ struct vm_region_list
   vm_size_t length;
 };

+#ifndef GDBSERVER
 struct obstack region_obstack;
+#endif

 /* Write gdb's LEN bytes from MYADDR and copy it to ADDR in inferior
    task's address space.  */
@@ -2344,7 +2518,9 @@ gnu_write_inferior (task_t task, CORE_ADDR addr,
char *myaddr, int length)
    myaddr, length);
   CHK_GOTO_OUT ("Write to inferior faulted", err);

+#ifndef GDBSERVER
   obstack_init (&region_obstack);
+#endif

   /* Do writes atomically.
      First check for holes and unwritable memory.  */
@@ -2399,7 +2575,11 @@ gnu_write_inferior (task_t task, CORE_ADDR
addr, char *myaddr, int length)
  /* Chain the regions for later use.  */
  region_element =
   (struct vm_region_list *)
+#ifndef GDBSERVER
   obstack_alloc (&region_obstack, sizeof (struct vm_region_list));
+#else
+  malloc (sizeof (struct vm_region_list));
+#endif

  region_element->protection = protection;
  region_element->start = region_address;
@@ -2454,7 +2634,9 @@ gnu_write_inferior (task_t task, CORE_ADDR addr,
char *myaddr, int length)
 out:
   if (deallocate)
     {
+#ifndef GDBSERVER
       obstack_free (&region_obstack, 0);
+#endif

       (void) vm_deallocate (mach_task_self (),
     copied,
@@ -2470,7 +2652,7 @@ out:
   return length;
 }

-
+#ifndef GDBSERVER
 /* Return 0 on failure, number of bytes handled otherwise.  TARGET
    is ignored.  */
 static int
@@ -2576,8 +2758,7 @@ gnu_find_memory_regions
(find_memory_region_ftype func, void *data)

   return 0;
 }
-
-
+#endif
 /* Return printable description of proc.  */
 char *
 proc_string (struct proc *proc)
@@ -2592,6 +2773,7 @@ proc_string (struct proc *proc)
   return tid_str;
 }

+#ifndef GDBSERVER
 static char *
 gnu_pid_to_str (struct target_ops *ops, ptid_t ptid)
 {
@@ -3452,3 +3634,214 @@ flush_inferior_icache (CORE_ADDR pc, int amount)
     warning (_("Error flushing inferior's cache : %s"), safe_strerror (ret));
 }
 #endif /* FLUSH_INFERIOR_CACHE */
+
+#else
+
+static ptid_t
+gnu_ptid_build (int pid, long lwp, long tid)
+{
+  return ptid_build (pid, tid, 0);
+}
+
+static long
+gnu_get_tid (ptid_t ptid)
+{
+  return ptid_get_lwp (ptid);
+}
+
+static struct process_info *
+gnu_add_process (int pid, int attached)
+{
+  struct process_info *proc;
+
+  proc = add_process (pid, attached);
+  proc->tdesc = gnu_tdesc;
+  proc->private = xcalloc (1, sizeof (*proc->private));
+  proc->private->inf = cur_inf ();
+  struct inf *inf = gnu_current_inf;
+
+  inf_attach (inf, pid);
+  inf->pending_execs = 2;
+  inf->nomsg = 1;
+  inf->traced = 1;
+
+  inf_resume (inf);
+
+  return proc;
+}
+
+static void
+gnu_join (int pid)
+{
+  /* doesn't need */
+}
+
+static void
+gnu_resume (struct thread_resume *resume_info, size_t n)
+{
+  /* FIXME: Assume for now that n == 1.  */
+  ptid_t ptid = resume_info[0].thread;
+  const int step = (resume_info[0].kind == resume_step ? 1 : 0); //1
means step, 0 means contiune
+  const int signal = resume_info[0].sig;
+  if (ptid_equal (ptid, minus_one_ptid))
+    ptid = thread_to_gdb_id (current_inferior);
+
+  regcache_invalidate ();
+
+  gnu_debug ("in gnu_resume: ptid=%d, step=%d, signal=%d\n", ptid, step,
+     signal);
+
+  /*my_resume(); */
+  /*static void gnu_resume_1 (struct target_ops *ops,ptid_t ptid, int
step, enum gdb_signal sig) */
+  gnu_resume_1 (NULL, ptid, step, signal);
+
+}
+
+static ptid_t
+gnu_wait (ptid_t ptid, struct target_waitstatus *status, int target_options)
+{
+  ptid_t event_ptid;
+  gnu_debug ("gnu_wait: [%s]", target_pid_to_str (ptid));
+  event_ptid = gnu_wait_1 (ptid, status, target_options);
+  gnu_debug ("          -> (status->kind = %d)\n", status->kind);
+  return event_ptid;
+}
+
+void
+gnu_fetch_registers_wrap (struct regcache *regcache, int regno)
+{
+  gnu_debug ("gnu_fetch_registers() regno=%d\n", regno);
+  return gnu_fetch_registers (NULL, regcache, regno);
+}
+
+void
+gnu_store_registers_wrap (struct regcache *regcache, int regno)
+{
+  gnu_debug ("gnu_store_registers() regno=%d\n", regno);
+  return gnu_store_registers (NULL, regcache, regno);
+}
+
+static int
+gnu_read_memory (CORE_ADDR addr, unsigned char *myaddr, int length)
+{
+  int ret = 0;
+  task_t task = (gnu_current_inf
+ ? (gnu_current_inf->task
+    ? gnu_current_inf->task->port : 0) : 0);
+  if (task == MACH_PORT_NULL)
+    return 0;
+  ret = gnu_read_inferior (task, addr, myaddr, length);
+  if (length != ret)
+    {
+      gnu_debug ("gnu_read_inferior,length=%d, but return %d\n", length, ret);
+      return -1;
+    }
+  return 0;
+}
+
+static int
+gnu_write_memory (CORE_ADDR addr, const unsigned char *myaddr, int length)
+{
+  int ret = 0;
+  task_t task = (gnu_current_inf
+ ? (gnu_current_inf->task
+    ? gnu_current_inf->task->port : 0) : 0);
+  if (task == MACH_PORT_NULL)
+    return 0;
+  ret = gnu_write_inferior (task, addr, myaddr, length);
+  if (length != ret)
+    {
+      gnu_debug ("gnu_write_inferior,length=%d, but return %d\n", length,
+ ret);
+      return -1;
+    }
+  return 0;
+}
+
+static void
+gnu_request_interrupt (void)
+{
+  printf ("gnu_request_interrupt not support!\n");
+  exit (-1);
+}
+
+/* Helper function for child_wait and the derivatives of child_wait.
+   HOSTSTATUS is the waitstatus from wait() or the equivalent; store our
+   translation of that in OURSTATUS.  */
+void
+store_waitstatus (struct target_waitstatus *ourstatus, int hoststatus)
+{
+  if (WIFEXITED (hoststatus))
+    {
+      ourstatus->kind = TARGET_WAITKIND_EXITED;
+      ourstatus->value.integer = WEXITSTATUS (hoststatus);
+    }
+  else if (!WIFSTOPPED (hoststatus))
+    {
+      ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
+      ourstatus->value.sig = gdb_signal_from_host (WTERMSIG (hoststatus));
+    }
+  else
+    {
+      ourstatus->kind = TARGET_WAITKIND_STOPPED;
+      ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (hoststatus));
+    }
+}
+
+static struct target_ops gnu_target_ops = {
+  gnu_create_inferior,
+  gnu_attach,
+  gnu_kill,
+  gnu_detach,
+  gnu_mourn,
+  gnu_join,
+  gnu_thread_alive,
+  gnu_resume,
+  gnu_wait,
+  gnu_fetch_registers_wrap,
+  gnu_store_registers_wrap,
+  NULL, /* prepare_to_access_memory */
+  NULL, /* done_accessing_memory */
+  gnu_read_memory,
+  gnu_write_memory,
+  NULL, /* look_up_symbols */
+  gnu_request_interrupt,
+  NULL, /* read_auxv */
+  NULL, /* insert_point */
+  NULL, /* remove_point */
+  NULL, /* stopped_by_watchpoint */
+  NULL, /* stopped_data_address */
+  NULL, /* read_offsets */
+  NULL, /* get_tls_address */
+  NULL, /* qxfer_spu */
+  NULL, /* hostio_last_error */
+  NULL, /* qxfer_osdata */
+  NULL, /* qxfer_siginfo */
+  NULL, /* supports_non_stop */
+  NULL, /* async */
+  NULL, /* start_non_stop */
+  NULL, /* supports_multi_process */
+  NULL, /* handle_monitor_command */
+};
+
+void
+_initialize_gnu_nat (void)
+{
+  proc_server = getproc ();
+}
+
+static void
+initialize_low_arch ()
+{
+  init_registers_i386 ();
+  gnu_tdesc = tdesc_i386;
+}
+
+void
+initialize_low (void)
+{
+  set_target_ops (&gnu_target_ops);
+  initialize_low_arch ();
+  _initialize_gnu_nat ();
+}
+#endif
diff --git a/gdb/gnu-nat.h b/gdb/gnu-nat.h
index f896bd2..84f507d 100644
--- a/gdb/gnu-nat.h
+++ b/gdb/gnu-nat.h
@@ -93,13 +93,83 @@ extern char *proc_string (struct proc *proc);

 extern int gnu_debug_flag;

+#ifndef GDBSERVER
 #define debug(msg, args...) \
  do { if (gnu_debug_flag) \
         fprintf_unfiltered (gdb_stdlog, "%s:%d: " msg "\r\n", \
     __FILE__ , __LINE__ , ##args); } while (0)
+#else
+#define debug(msg, args...) \
+ do { if (gnu_debug_flag) \
+        printf ("%s:%d: " msg "\r\n", \
+    __FILE__ , __LINE__ , ##args); } while (0)
+#endif

 /* Create a prototype generic GNU/Hurd target.  The client can
    override it with local methods.  */
 struct target_ops *gnu_target (void);

+#ifdef GDBSERVER
+
+/* All info needed to access an architecture/mode's registers.  */
+
+struct regs_info
+{
+  /* Regset support bitmap: 1 for registers that are transferred as a part
+     of a regset, 0 for ones that need to be handled individually.  This
+     can be NULL if all registers are transferred with regsets or regsets
+     are not supported.  */
+  unsigned char *regset_bitmap;
+
+  /* Info used when accessing registers with PTRACE_PEEKUSER /
+     PTRACE_POKEUSER.  This can be NULL if all registers are
+     transferred with regsets  .*/
+  struct usrregs_info *usrregs;
+
+#ifdef HAVE_gnu_REGSETS
+  /* Info used when accessing registers with regsets.  */
+  struct regsets_info *regsets_info;
+#endif
+};
+
+#define ptid_of(proc) ((proc)->head.id)
+#define pid_of(proc) ptid_get_pid ((proc)->head.id)
+#define lwpid_of(proc) ptid_get_lwp ((proc)->head.id)
+
+#define get_lwp(inf) ((struct lwp_info *)(inf))
+#define get_thread_lwp(thr) (get_lwp (inferior_target_data (thr)))
+#define get_lwp_thread(proc) ((struct thread_info *) \
+      find_inferior_id (&all_threads, \
+ get_lwp (proc)->head.id))
+
+#define THREAD_STATE_FLAVOR i386_REGS_SEGS_STATE
+#define THREAD_STATE_SIZE i386_THREAD_STATE_COUNT
+#define THREAD_STATE_SET_TRACED(state) \
+   ((struct i386_thread_state *) (state))->efl |= 0x100
+#define THREAD_STATE_CLEAR_TRACED(state) \
+   ((((struct i386_thread_state *) (state))->efl &= ~0x100), 1)
+
+
+#ifndef PIDGET
+#define PIDGET(PTID) (ptid_get_pid (PTID))
+#define TIDGET(PTID) (ptid_get_lwp (PTID))
+#define MERGEPID(PID, TID) ptid_build (PID, TID, 0)
+#endif
+//gdbserver use ptid_t not the same as gdb does!
+static ptid_t gnu_ptid_build(int pid,long lwp,long tid);
+
+//add for erase warning
+extern const char * host_address_to_string (const void *addr);
+
+/* Return printable description of proc.  */
+extern char *proc_string (struct proc *proc);
+
+
+#ifndef safe_strerror
+#define safe_strerror(err) \
+ ""
+#endif
+#endif
+
 #endif /* __GNU_NAT_H__ */
+
diff --git a/gdb/i386gnu-nat.c b/gdb/i386gnu-nat.c
index 0fd8d91..51ca679 100644
--- a/gdb/i386gnu-nat.c
+++ b/gdb/i386gnu-nat.c
@@ -17,24 +17,17 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

+#ifndef GDBSERVER
 #include "defs.h"
 #include "inferior.h"
 #include "floatformat.h"
 #include "regcache.h"

 #include "gdb_assert.h"
-#include <errno.h>
-#include <stdio.h>
 #include "gdb_string.h"

-#include <mach.h>
-#include <mach_error.h>
-#include <mach/message.h>
-#include <mach/exception.h>
-
 #include "i386-tdep.h"

-#include "gnu-nat.h"
 #include "i387-tdep.h"

 #ifdef HAVE_SYS_PROCFS_H
@@ -42,6 +35,24 @@
 # include "gregset.h"
 #endif

+#else /* GDBSERVER */
+#include "server.h"
+#include "target.h"
+#include "gdb_wait.h"
+
+#define I386_NUM_GREGS 16
+#endif /* GDBSERVER */
+
+#include <errno.h>
+#include <stdio.h>
+
+#include <mach.h>
+#include <mach_error.h>
+#include <mach/message.h>
+#include <mach/exception.h>
+#include "gnu-nat.h"
+/*#include "gnu-low.h"*/
+
 /* Offset to the thread_state_t location where REG is stored.  */
 #define REG_OFFSET(reg) offsetof (struct i386_thread_state, reg)

@@ -78,6 +89,7 @@ static int creg_offset[] =
 static void
 fetch_fpregs (struct regcache *regcache, struct proc *thread)
 {
+#ifndef GDBSERVER
   mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
   struct i386_float_state state;
   error_t err;
@@ -101,8 +113,12 @@ fetch_fpregs (struct regcache *regcache, struct
proc *thread)
       /* Supply the floating-point registers.  */
       i387_supply_fsave (regcache, -1, state.hw_state);
     }
+#else
+  gnu_debug ("fetch_fpregs() not support now\n");
+#endif
 }

+#ifndef GDBSERVER
 #ifdef HAVE_SYS_PROCFS_H
 /* These two calls are used by the core-regset.c code for
    reading ELF core files.  */
@@ -120,9 +136,16 @@ supply_fpregset (struct regcache *regcache, const
gdb_fpregset_t *fpregs)
   i387_supply_fsave (regcache, -1, fpregs);
 }
 #endif
+#endif

+extern struct inf *gnu_current_inf;
+extern ptid_t inferior_ptid;
 /* Fetch register REGNO, or all regs if REGNO is -1.  */
+#ifndef GDBSERVER
 static void
+#else
+void
+#endif
 gnu_fetch_registers (struct target_ops *ops,
      struct regcache *regcache, int regno)
 {
@@ -132,7 +155,11 @@ gnu_fetch_registers (struct target_ops *ops,
   inf_update_procs (gnu_current_inf);

   thread = inf_tid_to_thread (gnu_current_inf,
+#ifndef GDBSERVER
       ptid_get_tid (inferior_ptid));
+#else
+      TIDGET (inferior_ptid));
+#endif
   if (!thread)
     error (_("Can't fetch registers from thread %s: No such thread"),
    target_pid_to_str (inferior_ptid));
@@ -157,17 +184,25 @@ gnu_fetch_registers (struct target_ops *ops,
   proc_debug (thread, "fetching all register");

   for (i = 0; i < I386_NUM_GREGS; i++)
+#ifndef GDBSERVER
     regcache_raw_supply (regcache, i, REG_ADDR (state, i));
+#else
+    supply_register (regcache, i, REG_ADDR (state, i));
+#endif
   thread->fetched_regs = ~0;
  }
       else
  {
+#ifndef GDBSERVER
   proc_debug (thread, "fetching register %s",
       gdbarch_register_name (get_regcache_arch (regcache),
      regno));

   regcache_raw_supply (regcache, regno,
        REG_ADDR (state, regno));
+#else
+  supply_register (regcache, regno, REG_ADDR (state, regno));
+#endif
   thread->fetched_regs |= (1 << regno);
  }
     }
@@ -183,9 +218,14 @@ gnu_fetch_registers (struct target_ops *ops,

 /* Store the whole floating-point state into THREAD using information
    from the corresponding (pseudo) registers.  */
+#ifndef GDBSERVER
 static void
+#else
+void
+#endif
 store_fpregs (const struct regcache *regcache, struct proc *thread, int regno)
 {
+#ifndef GDBSERVER
   mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
   struct i386_float_state state;
   error_t err;
@@ -211,21 +251,36 @@ store_fpregs (const struct regcache *regcache,
struct proc *thread, int regno)
        proc_string (thread));
       return;
     }
+#else
+  gnu_debug ("store_fpregs() not support now\n");
+#endif
 }

 /* Store at least register REGNO, or all regs if REGNO == -1.  */
+#ifndef GDBSERVER
 static void
+#else
+void
+#endif
 gnu_store_registers (struct target_ops *ops,
      struct regcache *regcache, int regno)
 {
   struct proc *thread;
+#ifndef GDBSERVER
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
+#else
+  const struct target_desc *gdbarch = regcache->tdesc;
+#endif

   /* Make sure we know about new threads.  */
   inf_update_procs (gnu_current_inf);

   thread = inf_tid_to_thread (gnu_current_inf,
+#ifndef GDBSERVER
       ptid_get_tid (inferior_ptid));
+#else
+        TIDGET (inferior_ptid));
+#endif
   if (!thread)
     error (_("Couldn't store registers into thread %s: No such thread"),
    target_pid_to_str (inferior_ptid));
@@ -265,12 +320,19 @@ gnu_store_registers (struct target_ops *ops,
    register_size (gdbarch, check_regno)))
       /* Register CHECK_REGNO has changed!  Ack!  */
       {
+#ifndef GDBSERVER
  warning (_("Register %s changed after the thread was aborted"),
  gdbarch_register_name (gdbarch, check_regno));
+#endif
  if (regno >= 0 && regno != check_regno)
   /* Update GDB's copy of the register.  */
+#ifndef GDBSERVER
   regcache_raw_supply (regcache, check_regno,
        REG_ADDR (state, check_regno));
+#else
+  supply_register (regcache, check_regno,
+   REG_ADDR (state, check_regno));
+#endif
  else
   warning (_("... also writing this register!  "
      "Suspicious..."));
@@ -284,16 +346,24 @@ gnu_store_registers (struct target_ops *ops,
   proc_debug (thread, "storing all registers");

   for (i = 0; i < I386_NUM_GREGS; i++)
+#ifndef GDBSERVER
     if (REG_VALID == regcache_register_status (regcache, i))
       regcache_raw_collect (regcache, i, REG_ADDR (state, i));
+#else
+    collect_register (regcache, i, REG_ADDR (state, i));
+#endif
  }
       else
  {
+#ifndef GDBSERVER
   proc_debug (thread, "storing register %s",
       gdbarch_register_name (gdbarch, regno));

   gdb_assert (REG_VALID == regcache_register_status (regcache, regno));
   regcache_raw_collect (regcache, regno, REG_ADDR (state, regno));
+#else
+  collect_register (regcache, regno, REG_ADDR (state, regno));
+#endif
  }

       /* Restore the T bit.  */
@@ -309,6 +379,7 @@ gnu_store_registers (struct target_ops *ops,
     }
 }

+#ifndef GDBSERVER
 /* Provide a prototype to silence -Wmissing-prototypes.  */
 extern initialize_file_ftype _initialize_i386gnu_nat;

@@ -326,3 +397,4 @@ _initialize_i386gnu_nat (void)
   /* Register the target.  */
   add_target (t);
 }
+#endif

======================================================================
gdbserver
        * configure.ac (host_makefile_frag): New rule for GNU/Hurd to load
        i386gnu.mh.
        * configure.srv (srv_tgtobj): Add gnu-nat.o i386gnu-nat.o.o for
        GNU/Hurd.
        (srv_regobj): Add $(srv_i386_regobj) for GNU/Hurd.
        (srv_xmlfiles): Add $(srv_i386_xmlfiles) for GNU/Hurd.
        * configure: Regenerate.
        * Makefile.in (OBS): Add $(NATDEPFILES).
        (generated_files): Add $(NAT_GENERATED_FILES).
        (@host_makefile_frag@): New rule, add gnui386.mh.
        (MIG): New tools.
        (AWK): New tools.
        * exc_request.defs: New file. Softlink to [gdb]/gdb/exc_request.defs.
        * i386gnu-nat.c: New file. Softlink to [gdb]/gdb/i386gnu-nat.c.
        * gnu-low.c: New file. Softlink to [gdb]/gdb/gnu-nat.c.
        * gnu-low.h: New file. Softlink to [gdb]/gdb/gnu-nat.h.
        * hostio.c: Add macro define PATH_MAX 512.
        * i386gnu.mh: New file. Softlink to [gdb]/gdb/config/i386/i386gnu.mh.
        * msg.defs: New file. Softlink to [gdb]/gdb/msg.defs.
        * msg_reply.defs: New file. Softlink to [gdb]/gdb/msg_reply.defs.
        * notify.defs: New file. Softlink to [gdb]/gdb/notify.defs.
        * process_reply.defs: New file. Softlink to
[gdb]/gdb/process_reply.defs.
        * reply_mid_hack.awk: New file. Softlink to
[gdb]/gdb/reply_mid_hack.awk.
        * server.h: Add typedef long CORE_ADDR;
        * utils.c (host_address_to_string): New functions, copy from
        [gdb]/gdb/utils.c.

diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index e8470a8..967cf57 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -50,6 +50,8 @@ INSTALL_DATA = @INSTALL_DATA@
 RANLIB = @RANLIB@

 CC = @CC@
+MIG = @MIG@
+AWK = @AWK@

 # Dependency tracking information.
 DEPMODE = @CCDEPMODE@
@@ -172,7 +174,7 @@ OBS = agent.o ax.o inferiors.o regcache.o
remote-utils.o server.o signals.o targ
  xml-utils.o common-utils.o ptid.o buffer.o format.o filestuff.o \
  dll.o notif.o tdesc.o \
  $(XML_BUILTIN) \
- $(DEPFILES) $(LIBOBJS)
+ $(DEPFILES) $(LIBOBJS) $(NATDEPFILES)
 GDBREPLAY_OBS = gdbreplay.o version.o
 GDBSERVER_LIBS = @GDBSERVER_LIBS@
 XM_CLIBS = @LIBS@
@@ -195,6 +197,11 @@ CLEANDIRS = $(SUBDIRS)
 # The format here is for the `case' shell command.
 REQUIRED_SUBDIRS = $(GNULIB_BUILDDIR)

+# Host-dependent makefile fragment comes in here.
address@hidden@
address@hidden@
+# End of host-dependent makefile fragment
+
 FLAGS_TO_PASS = \
  "prefix=$(prefix)" \
  "exec_prefix=$(exec_prefix)" \
@@ -228,7 +235,7 @@ FLAGS_TO_PASS = \
  "RUNTESTFLAGS=$(RUNTESTFLAGS)"

 # All generated files which can be included by another file.
-generated_files = config.h $(GNULIB_H)
+generated_files = config.h $(GNULIB_H) $(NAT_GENERATED_FILES)

 .c.o:
  $(COMPILE) $<
diff --git a/gdb/gdbserver/configure.ac b/gdb/gdbserver/configure.ac
index b9928d7..21685db 100644
--- a/gdb/gdbserver/configure.ac
+++ b/gdb/gdbserver/configure.ac
@@ -456,6 +456,31 @@ if $want_ipa ; then
    fi
 fi

+frags=
+GDBSERVER=1
+case $host_os in
+  gnu*)
+    #Needed for GNU Hurd hosts.
+    AC_PROG_AWK
+    AC_CHECK_TOOL(MIG, mig)
+    if test x"$MIG" = x; then
+      AC_MSG_ERROR([MIG not found but required for $host hosts])
+    fi
+    host_makefile_frag=${srcdir}/i386gnu.mh
+    if test ! -f ${host_makefile_frag}; then
+       AC_MSG_ERROR("*** Gdb does not support native target ${host}")
+    fi
+    frags="$frags $host_makefile_frag"
+    ;;
+  *)
+    host_makefile_frag=/dev/null
+    ;;
+esac
+
+AC_SUBST_FILE(host_makefile_frag)
+AC_SUBST(frags)
+AC_SUBST(GDBSERVER)
+
 AC_SUBST(GDBSERVER_DEPFILES)
 AC_SUBST(GDBSERVER_LIBS)
 AC_SUBST(srv_xmlbuiltin)
diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
index 879d0de..1d9bf7a 100644
--- a/gdb/gdbserver/configure.srv
+++ b/gdb/gdbserver/configure.srv
@@ -118,6 +118,11 @@ case "${target}" in
  srv_linux_btrace=yes
  ipa_obj="${ipa_i386_linux_regobj} linux-i386-ipa.o"
  ;;
+  i[34567]86-*-gnu*) srv_regobj="$srv_i386_regobj"
+ srv_tgtobj="gnu-nat.o i386gnu-nat.o"
+ srv_xmlfiles="$srv_i386_xmlfiles"
+ ;;
+
   i[34567]86-*-lynxos*) srv_regobj="i386.o"
  srv_tgtobj="lynx-low.o lynx-i386-low.o"
  srv_xmlfiles="i386/i386.xml"
diff --git a/gdb/gdbserver/exc_request.defs b/gdb/gdbserver/exc_request.defs
new file mode 120000
index 0000000..1b8d3cd
--- /dev/null
+++ b/gdb/gdbserver/exc_request.defs
@@ -0,0 +1 @@
+../exc_request.defs
\ No newline at end of file
diff --git a/gdb/gdbserver/gnu-nat.c b/gdb/gdbserver/gnu-nat.c
new file mode 120000
index 0000000..d72e184
--- /dev/null
+++ b/gdb/gdbserver/gnu-nat.c
@@ -0,0 +1 @@
+../gnu-nat.c
\ No newline at end of file
diff --git a/gdb/gdbserver/gnu-nat.h b/gdb/gdbserver/gnu-nat.h
new file mode 120000
index 0000000..397c15c
--- /dev/null
+++ b/gdb/gdbserver/gnu-nat.h
@@ -0,0 +1 @@
+../gnu-nat.h
\ No newline at end of file
diff --git a/gdb/gdbserver/hostio.c b/gdb/gdbserver/hostio.c
index df94d31..f3af499 100644
--- a/gdb/gdbserver/hostio.c
+++ b/gdb/gdbserver/hostio.c
@@ -25,6 +25,10 @@
 #include <limits.h>
 #include <unistd.h>

+#ifndef PATH_MAX
+#define PATH_MAX 512
+#endif
+
 extern int remote_debug;

 struct fd_list
diff --git a/gdb/gdbserver/i386gnu-nat.c b/gdb/gdbserver/i386gnu-nat.c
new file mode 120000
index 0000000..c547b9b
--- /dev/null
+++ b/gdb/gdbserver/i386gnu-nat.c
@@ -0,0 +1 @@
+../i386gnu-nat.c
\ No newline at end of file
diff --git a/gdb/gdbserver/i386gnu.mh b/gdb/gdbserver/i386gnu.mh
new file mode 120000
index 0000000..0497c22
--- /dev/null
+++ b/gdb/gdbserver/i386gnu.mh
@@ -0,0 +1 @@
+../config/i386/i386gnu.mh
\ No newline at end of file
diff --git a/gdb/gdbserver/msg.defs b/gdb/gdbserver/msg.defs
new file mode 120000
index 0000000..a663adb
--- /dev/null
+++ b/gdb/gdbserver/msg.defs
@@ -0,0 +1 @@
+../msg.defs
\ No newline at end of file
diff --git a/gdb/gdbserver/msg_reply.defs b/gdb/gdbserver/msg_reply.defs
new file mode 120000
index 0000000..61e8053
--- /dev/null
+++ b/gdb/gdbserver/msg_reply.defs
@@ -0,0 +1 @@
+../msg_reply.defs
\ No newline at end of file
diff --git a/gdb/gdbserver/notify.defs b/gdb/gdbserver/notify.defs
new file mode 120000
index 0000000..8a2c79d
--- /dev/null
+++ b/gdb/gdbserver/notify.defs
@@ -0,0 +1 @@
+../notify.defs
\ No newline at end of file
diff --git a/gdb/gdbserver/process_reply.defs b/gdb/gdbserver/process_reply.defs
new file mode 120000
index 0000000..7106ac0
--- /dev/null
+++ b/gdb/gdbserver/process_reply.defs
@@ -0,0 +1 @@
+../process_reply.defs
\ No newline at end of file
diff --git a/gdb/gdbserver/reply_mig_hack.awk b/gdb/gdbserver/reply_mig_hack.awk
new file mode 120000
index 0000000..fa7d33a
--- /dev/null
+++ b/gdb/gdbserver/reply_mig_hack.awk
@@ -0,0 +1 @@
+../reply_mig_hack.awk
\ No newline at end of file
diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h
index 18d060c..20e88bf 100644
--- a/gdb/gdbserver/server.h
+++ b/gdb/gdbserver/server.h
@@ -91,7 +91,8 @@ typedef unsigned char gdb_byte;

 /* FIXME: This should probably be autoconf'd for.  It's an integer type at
    least the size of a (void *).  */
-typedef long long CORE_ADDR;
+//typedef long long CORE_ADDR;
+typedef long CORE_ADDR;

 typedef long long LONGEST;
 typedef unsigned long long ULONGEST;
diff --git a/gdb/gdbserver/utils.c b/gdb/gdbserver/utils.c
index 9706d74..d6dd4f9 100644
--- a/gdb/gdbserver/utils.c
+++ b/gdb/gdbserver/utils.c
@@ -170,7 +170,6 @@ internal_error (const char *file, int line, const
char *fmt, ...)
 #define CELLSIZE 50

 /* Return the next entry in the circular buffer.  */
-
 static char *
 get_cell (void)
 {
@@ -181,6 +180,15 @@ get_cell (void)
   return buf[cell];
 }

+const char *
+host_address_to_string (const void *addr)
+{
+  char *str = get_cell ();
+
+  xsnprintf (str, CELLSIZE, "0x%s", phex_nz ((unsigned long long)
addr, sizeof (addr)));
+  return str;
+}
+
 static char *
 decimal2str (char *sign, ULONGEST addr)
 {

-- 
Yue Lu (陆岳)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]