Adjust Value.location for lval_register
[deliverable/binutils-gdb.git] / gdb / go32-nat.c
index a92a34f46e04c0a5cf5687a07548430893524a1a..6e608e2e83b3f9123bede33338b4f5f9b7e9c98e 100644 (file)
@@ -1,5 +1,5 @@
 /* Native debugging support for Intel x86 running DJGPP.
-   Copyright (C) 1997-2013 Free Software Foundation, Inc.
+   Copyright (C) 1997-2016 Free Software Foundation, Inc.
    Written by Robert Hoehne.
 
    This file is part of GDB.
@@ -85,8 +85,9 @@
 
 #include <fcntl.h>
 
-#include "i386-nat.h"
+#include "x86-nat.h"
 #include "inferior.h"
+#include "infrun.h"
 #include "gdbthread.h"
 #include "gdb_wait.h"
 #include "gdbcore.h"
 #include "buildsym.h"
 #include "i387-tdep.h"
 #include "i386-tdep.h"
-#include "i386-cpuid.h"
+#include "nat/x86-cpuid.h"
 #include "value.h"
 #include "regcache.h"
-#include "gdb_string.h"
 #include "top.h"
 #include "cli/cli-utils.h"
+#include "inf-child.h"
 
-#include <stdio.h>             /* might be required for __DJGPP_MINOR__ */
-#include <stdlib.h>
 #include <ctype.h>
-#include <errno.h>
 #include <unistd.h>
 #include <sys/utsname.h>
 #include <io.h>
@@ -234,34 +232,7 @@ static int dr_ref_count[4];
 #define SOME_PID 42
 
 static int prog_has_started = 0;
-static void go32_open (char *name, int from_tty);
-static void go32_close (void);
-static void go32_attach (struct target_ops *ops, char *args, int from_tty);
-static void go32_detach (struct target_ops *ops, char *args, int from_tty);
-static void go32_resume (struct target_ops *ops,
-                        ptid_t ptid, int step,
-                        enum gdb_signal siggnal);
-static void go32_fetch_registers (struct target_ops *ops,
-                                 struct regcache *, int regno);
-static void store_register (const struct regcache *, int regno);
-static void go32_store_registers (struct target_ops *ops,
-                                 struct regcache *, int regno);
-static void go32_prepare_to_store (struct regcache *);
-static int go32_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len,
-                            int write,
-                            struct mem_attrib *attrib,
-                            struct target_ops *target);
-static void go32_files_info (struct target_ops *target);
-static void go32_kill_inferior (struct target_ops *ops);
-static void go32_create_inferior (struct target_ops *ops, char *exec_file,
-                                 char *args, char **env, int from_tty);
 static void go32_mourn_inferior (struct target_ops *ops);
-static int go32_can_run (void);
-
-static struct target_ops go32_ops;
-static void go32_terminal_init (void);
-static void go32_terminal_inferior (void);
-static void go32_terminal_ours (void);
 
 #define r_ofs(x) (offsetof(TSS,x))
 
@@ -365,29 +336,13 @@ static struct {
 };
 
 static void
-go32_open (char *name, int from_tty)
-{
-  printf_unfiltered ("Done.  Use the \"run\" command to run the program.\n");
-}
-
-static void
-go32_close (void)
-{
-}
-
-static void
-go32_attach (struct target_ops *ops, char *args, int from_tty)
+go32_attach (struct target_ops *ops, const char *args, int from_tty)
 {
   error (_("\
 You cannot attach to a running program on this platform.\n\
 Use the `run' command to run DJGPP programs."));
 }
 
-static void
-go32_detach (struct target_ops *ops, const char *args, int from_tty)
-{
-}
-
 static int resume_is_step;
 static int resume_signal = -1;
 
@@ -597,36 +552,67 @@ go32_store_registers (struct target_ops *ops,
     }
 }
 
-static void
-go32_prepare_to_store (struct regcache *regcache)
-{
-}
+/* Const-correct version of DJGPP's write_child, which unfortunately
+   takes a non-const buffer pointer.  */
 
 static int
-go32_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int write,
-                 struct mem_attrib *attrib, struct target_ops *target)
+my_write_child (unsigned child_addr, const void *buf, unsigned len)
 {
-  if (write)
+  static void *buffer = NULL;
+  static unsigned buffer_len = 0;
+  int res;
+
+  if (buffer_len < len)
     {
-      if (write_child (memaddr, myaddr, len))
-       {
-         return 0;
-       }
-      else
-       {
-         return len;
-       }
+      buffer = xrealloc (buffer, len);
+      buffer_len = len;
     }
+
+  memcpy (buffer, buf, len);
+  res = write_child (child_addr, buffer, len);
+  return res;
+}
+
+/* Helper for go32_xfer_partial that handles memory transfers.
+   Arguments are like target_xfer_partial.  */
+
+static enum target_xfer_status
+go32_xfer_memory (gdb_byte *readbuf, const gdb_byte *writebuf,
+                 ULONGEST memaddr, ULONGEST len, ULONGEST *xfered_len)
+{
+  int res;
+
+  if (writebuf != NULL)
+    res = my_write_child (memaddr, writebuf, len);
   else
+    res = read_child (memaddr, readbuf, len);
+
+  /* read_child and write_child return zero on success, non-zero on
+     failure.  */
+  if (res != 0)
+    return TARGET_XFER_E_IO;
+
+  *xfered_len = len;
+  return TARGET_XFER_OK;
+}
+
+/* Target to_xfer_partial implementation.  */
+
+static enum target_xfer_status
+go32_xfer_partial (struct target_ops *ops, enum target_object object,
+                  const char *annex, gdb_byte *readbuf,
+                  const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
+                  ULONGEST *xfered_len)
+{
+  switch (object)
     {
-      if (read_child (memaddr, myaddr, len))
-       {
-         return 0;
-       }
-      else
-       {
-         return len;
-       }
+    case TARGET_OBJECT_MEMORY:
+      return go32_xfer_memory (readbuf, writebuf, offset, len, xfered_len);
+
+    default:
+      return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
+                                           readbuf, writebuf, offset, len,
+                                           xfered_len);
     }
 }
 
@@ -654,6 +640,7 @@ go32_create_inferior (struct target_ops *ops, char *exec_file,
   char **env_save = environ;
   size_t cmdlen;
   struct inferior *inf;
+  int result;
 
   /* If no exec file handed to us, get it from the exec-file command -- with
      a good, common error message if none is specified.  */
@@ -690,7 +677,7 @@ go32_create_inferior (struct target_ops *ops, char *exec_file,
   if (cmdlen > 1024*1024)
     error (_("Command line too long."));
 
-  cmdline = xmalloc (cmdlen + 4);
+  cmdline = (char *) xmalloc (cmdlen + 4);
   strcpy (cmdline + 1, args);
   /* If the command-line length fits into DOS 126-char limits, use the
      DOS command tail format; otherwise, tell v2loadimage to pass it
@@ -705,15 +692,14 @@ go32_create_inferior (struct target_ops *ops, char *exec_file,
 
   environ = env;
 
-  if (v2loadimage (exec_file, cmdline, start_state))
-    {
-      environ = env_save;
-      printf_unfiltered ("Load failed for image %s\n", exec_file);
-      exit (1);
-    }
+  result = v2loadimage (exec_file, cmdline, start_state);
+
   environ = env_save;
   xfree (cmdline);
 
+  if (result != 0)
+    error (_("Load failed for image %s"), exec_file);
+
   edi_init (start_state);
 #if __DJGPP_MINOR__ < 3
   save_npx ();
@@ -723,11 +709,12 @@ go32_create_inferior (struct target_ops *ops, char *exec_file,
   inf = current_inferior ();
   inferior_appeared (inf, SOME_PID);
 
-  push_target (&go32_ops);
+  if (!target_is_pushed (ops))
+    push_target (ops);
 
   add_thread_silent (inferior_ptid);
 
-  clear_proceed_status ();
+  clear_proceed_status (0);
   insert_breakpoints ();
   prog_has_started = 1;
 }
@@ -750,21 +737,15 @@ go32_mourn_inferior (struct target_ops *ops)
      be nice if GDB itself would take care to remove all breakpoints
      at all times, but it doesn't, probably under an assumption that
      the OS cleans up when the debuggee exits.  */
-  i386_cleanup_dregs ();
+  x86_cleanup_dregs ();
 
   ptid = inferior_ptid;
   inferior_ptid = null_ptid;
   delete_thread_silent (ptid);
   prog_has_started = 0;
 
-  unpush_target (ops);
   generic_mourn_inferior ();
-}
-
-static int
-go32_can_run (void)
-{
-  return 1;
+  inf_child_maybe_unpush_target (ops);
 }
 
 /* Hardware watchpoint support.  */
@@ -870,14 +851,14 @@ static int inf_terminal_mode;
 static int terminal_is_ours = 1;
 
 static void
-go32_terminal_init (void)
+go32_terminal_init (struct target_ops *self)
 {
   inf_mode_valid = 0;  /* Reinitialize, in case they are restarting child.  */
   terminal_is_ours = 1;
 }
 
 static void
-go32_terminal_info (const char *args, int from_tty)
+go32_terminal_info (struct target_ops *self, const char *args, int from_tty)
 {
   printf_unfiltered ("Inferior's terminal is in %s mode.\n",
                     !inf_mode_valid
@@ -907,7 +888,7 @@ go32_terminal_info (const char *args, int from_tty)
 }
 
 static void
-go32_terminal_inferior (void)
+go32_terminal_inferior (struct target_ops *self)
 {
   /* Redirect standard handles as child wants them.  */
   errno = 0;
@@ -928,7 +909,7 @@ go32_terminal_inferior (void)
 }
 
 static void
-go32_terminal_ours (void)
+go32_terminal_ours (struct target_ops *self)
 {
   /* Switch to cooked mode on the gdb terminal and save the inferior
      terminal mode to be restored when it is resumed.  */
@@ -966,68 +947,32 @@ go32_pid_to_str (struct target_ops *ops, ptid_t ptid)
   return normal_pid_to_str (ptid);
 }
 
-static void
-init_go32_ops (void)
-{
-  go32_ops.to_shortname = "djgpp";
-  go32_ops.to_longname = "djgpp target process";
-  go32_ops.to_doc =
-    "Program loaded by djgpp, when gdb is used as an external debugger";
-  go32_ops.to_open = go32_open;
-  go32_ops.to_close = go32_close;
-  go32_ops.to_attach = go32_attach;
-  go32_ops.to_detach = go32_detach;
-  go32_ops.to_resume = go32_resume;
-  go32_ops.to_wait = go32_wait;
-  go32_ops.to_fetch_registers = go32_fetch_registers;
-  go32_ops.to_store_registers = go32_store_registers;
-  go32_ops.to_prepare_to_store = go32_prepare_to_store;
-  go32_ops.deprecated_xfer_memory = go32_xfer_memory;
-  go32_ops.to_files_info = go32_files_info;
-  go32_ops.to_insert_breakpoint = memory_insert_breakpoint;
-  go32_ops.to_remove_breakpoint = memory_remove_breakpoint;
-  go32_ops.to_terminal_init = go32_terminal_init;
-  go32_ops.to_terminal_inferior = go32_terminal_inferior;
-  go32_ops.to_terminal_ours_for_output = go32_terminal_ours;
-  go32_ops.to_terminal_ours = go32_terminal_ours;
-  go32_ops.to_terminal_info = go32_terminal_info;
-  go32_ops.to_kill = go32_kill_inferior;
-  go32_ops.to_create_inferior = go32_create_inferior;
-  go32_ops.to_mourn_inferior = go32_mourn_inferior;
-  go32_ops.to_can_run = go32_can_run;
-  go32_ops.to_thread_alive = go32_thread_alive;
-  go32_ops.to_pid_to_str = go32_pid_to_str;
-  go32_ops.to_stratum = process_stratum;
-  go32_ops.to_has_all_memory = default_child_has_all_memory;
-  go32_ops.to_has_memory = default_child_has_memory;
-  go32_ops.to_has_stack = default_child_has_stack;
-  go32_ops.to_has_registers = default_child_has_registers;
-  go32_ops.to_has_execution = default_child_has_execution;
-
-  i386_use_watchpoints (&go32_ops);
-
-
-  i386_dr_low.set_control = go32_set_dr7;
-  i386_dr_low.set_addr = go32_set_dr;
-  i386_dr_low.get_status = go32_get_dr6;
-  i386_dr_low.get_control = go32_get_dr7;
-  i386_dr_low.get_addr = go32_get_dr;
-  i386_set_debug_register_length (4);
-
-  go32_ops.to_magic = OPS_MAGIC;
-
-  /* Initialize child's cwd as empty to be initialized when starting
-     the child.  */
-  *child_cwd = 0;
+/* Create a go32 target.  */
 
-  /* Initialize child's command line storage.  */
-  if (redir_debug_init (&child_cmd) == -1)
-    internal_error (__FILE__, __LINE__,
-                   _("Cannot allocate redirection storage: "
-                     "not enough memory.\n"));
-
-  /* We are always processing GCC-compiled programs.  */
-  processing_gcc_compilation = 2;
+static struct target_ops *
+go32_target (void)
+{
+  struct target_ops *t = inf_child_target ();
+
+  t->to_attach = go32_attach;
+  t->to_resume = go32_resume;
+  t->to_wait = go32_wait;
+  t->to_fetch_registers = go32_fetch_registers;
+  t->to_store_registers = go32_store_registers;
+  t->to_xfer_partial = go32_xfer_partial;
+  t->to_files_info = go32_files_info;
+  t->to_terminal_init = go32_terminal_init;
+  t->to_terminal_inferior = go32_terminal_inferior;
+  t->to_terminal_ours_for_output = go32_terminal_ours;
+  t->to_terminal_ours = go32_terminal_ours;
+  t->to_terminal_info = go32_terminal_info;
+  t->to_kill = go32_kill_inferior;
+  t->to_create_inferior = go32_create_inferior;
+  t->to_mourn_inferior = go32_mourn_inferior;
+  t->to_thread_alive = go32_thread_alive;
+  t->to_pid_to_str = go32_pid_to_str;
+
+  return t;
 }
 
 /* Return the current DOS codepage number.  */
@@ -1140,12 +1085,12 @@ go32_sysinfo (char *arg, int from_tty)
     {
       /* CPUID with EAX = 0 returns the Vendor ID.  */
 #if 0
-      /* Ideally we would use i386_cpuid(), but it needs someone to run
+      /* Ideally we would use x86_cpuid(), but it needs someone to run
          native tests first to make sure things actually work.  They should.
          http://sourceware.org/ml/gdb-patches/2013-05/msg00164.html  */
       unsigned int eax, ebx, ecx, edx;
 
-      if (i386_cpuid (0, &eax, &ebx, &ecx, &edx))
+      if (x86_cpuid (0, &eax, &ebx, &ecx, &edx))
        {
          cpuid_max = eax;
          memcpy (&vendor[0], &ebx, 4);
@@ -1198,7 +1143,7 @@ go32_sysinfo (char *arg, int from_tty)
 
 #if 0
       /* See comment above about cpuid usage.  */
-      i386_cpuid (1, &cpuid_eax, &cpuid_ebx, NULL, &cpuid_edx);
+      x86_cpuid (1, &cpuid_eax, &cpuid_ebx, NULL, &cpuid_edx);
 #else
       __asm__ __volatile__ ("movl   $1, %%eax;"
                            "cpuid;"
@@ -2117,8 +2062,30 @@ extern initialize_file_ftype _initialize_go32_nat;
 void
 _initialize_go32_nat (void)
 {
-  init_go32_ops ();
-  add_target (&go32_ops);
+  struct target_ops *t = go32_target ();
+
+  x86_dr_low.set_control = go32_set_dr7;
+  x86_dr_low.set_addr = go32_set_dr;
+  x86_dr_low.get_status = go32_get_dr6;
+  x86_dr_low.get_control = go32_get_dr7;
+  x86_dr_low.get_addr = go32_get_dr;
+  x86_set_debug_register_length (4);
+
+  x86_use_watchpoints (t);
+  add_target (t);
+
+  /* Initialize child's cwd as empty to be initialized when starting
+     the child.  */
+  *child_cwd = 0;
+
+  /* Initialize child's command line storage.  */
+  if (redir_debug_init (&child_cmd) == -1)
+    internal_error (__FILE__, __LINE__,
+                   _("Cannot allocate redirection storage: "
+                     "not enough memory.\n"));
+
+  /* We are always processing GCC-compiled programs.  */
+  processing_gcc_compilation = 2;
 
   add_prefix_cmd ("dos", class_info, go32_info_dos_command, _("\
 Print information specific to DJGPP (aka MS-DOS) debugging."),
This page took 0.027448 seconds and 4 git commands to generate.