Kill pthread_ops_hack
[deliverable/binutils-gdb.git] / gdb / go32-nat.c
index de5e58676d39c3976f12f8a729ba97d360ed720a..a7ab1375d0ead6f7a054b6e2264431bd10dfd360 100644 (file)
@@ -1,12 +1,13 @@
 /* Native debugging support for Intel x86 running DJGPP.
-   Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1999, 2000, 2001, 2005, 2006, 2007, 2008
+   Free Software Foundation, Inc.
    Written by Robert Hoehne.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   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,
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <fcntl.h>
 
 #include "defs.h"
 #include "inferior.h"
+#include "gdbthread.h"
 #include "gdb_wait.h"
 #include "gdbcore.h"
 #include "command.h"
 #include "gdbcmd.h"
 #include "floatformat.h"
 #include "buildsym.h"
-#include "i387-nat.h"
+#include "i387-tdep.h"
 #include "i386-tdep.h"
 #include "value.h"
 #include "regcache.h"
 #include "gdb_string.h"
+#include "top.h"
 
 #include <stdio.h>             /* might be required for __DJGPP_MINOR__ */
 #include <stdlib.h>
@@ -172,19 +173,20 @@ static void go32_resume (ptid_t ptid, int step,
                          enum target_signal siggnal);
 static ptid_t go32_wait (ptid_t ptid,
                                struct target_waitstatus *status);
-static void go32_fetch_registers (int regno);
-static void store_register (int regno);
-static void go32_store_registers (int regno);
-static void go32_prepare_to_store (void);
-static int go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
+static void go32_fetch_registers (struct regcache *, int regno);
+static void store_register (const struct regcache *, int regno);
+static void go32_store_registers (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_stop (void);
+static void go32_stop (ptid_t);
 static void go32_kill_inferior (void);
-static void go32_create_inferior (char *exec_file, char *args, char **env);
-static void go32_mourn_inferior (void);
+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;
@@ -305,15 +307,15 @@ go32_close (int quitting)
 }
 
 static void
-go32_attach (char *args, int from_tty)
+go32_attach (struct target_ops *ops, char *args, int from_tty)
 {
-  error ("\
+  error (_("\
 You cannot attach to a running program on this platform.\n\
-Use the `run' command to run DJGPP programs.");
+Use the `run' command to run DJGPP programs."));
 }
 
 static void
-go32_detach (char *args, int from_tty)
+go32_detach (struct target_ops *ops, char *args, int from_tty)
 {
 }
 
@@ -463,64 +465,70 @@ go32_wait (ptid_t ptid, struct target_waitstatus *status)
 }
 
 static void
-fetch_register (int regno)
+fetch_register (struct regcache *regcache, int regno)
 {
-  if (regno < FP0_REGNUM)
-    supply_register (regno, (char *) &a_tss + regno_mapping[regno].tss_ofs);
-  else if (FP_REGNUM_P (regno) || FPC_REGNUM_P (regno))
-    i387_supply_register (regno, (char *) &npx);
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  if (regno < gdbarch_fp0_regnum (gdbarch))
+    regcache_raw_supply (regcache, regno,
+                        (char *) &a_tss + regno_mapping[regno].tss_ofs);
+  else if (i386_fp_regnum_p (gdbarch, regno) || i386_fpc_regnum_p (gdbarch, regno))
+    i387_supply_fsave (regcache, regno, &npx);
   else
     internal_error (__FILE__, __LINE__,
-                   "Invalid register no. %d in fetch_register.", regno);
+                   _("Invalid register no. %d in fetch_register."), regno);
 }
 
 static void
-go32_fetch_registers (int regno)
+go32_fetch_registers (struct regcache *regcache, int regno)
 {
   if (regno >= 0)
-    fetch_register (regno);
+    fetch_register (regcache, regno);
   else
     {
-      for (regno = 0; regno < FP0_REGNUM; regno++)
-       fetch_register (regno);
-      i387_supply_fsave ((char *) &npx);
+      for (regno = 0;
+          regno < gdbarch_fp0_regnum (get_regcache_arch (regcache));
+          regno++)
+       fetch_register (regcache, regno);
+      i387_supply_fsave (regcache, -1, &npx);
     }
 }
 
 static void
-store_register (int regno)
+store_register (const struct regcache *regcache, int regno)
 {
-  if (regno < FP0_REGNUM)
-    regcache_collect (regno, (void *) &a_tss + regno_mapping[regno].tss_ofs);
-  else if (FP_REGNUM_P (regno) || FPC_REGNUM_P (regno))
-    i387_fill_fsave ((char *) &npx, regno);
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  if (regno < gdbarch_fp0_regnum (gdbarch))
+    regcache_raw_collect (regcache, regno,
+                         (char *) &a_tss + regno_mapping[regno].tss_ofs);
+  else if (i386_fp_regnum_p (gdbarch, regno) || i386_fpc_regnum_p (gdbarch, regno))
+    i387_collect_fsave (regcache, regno, &npx);
   else
     internal_error (__FILE__, __LINE__,
-                   "Invalid register no. %d in store_register.", regno);
+                   _("Invalid register no. %d in store_register."), regno);
 }
 
 static void
-go32_store_registers (int regno)
+go32_store_registers (struct regcache *regcache, int regno)
 {
   unsigned r;
 
   if (regno >= 0)
-    store_register (regno);
+    store_register (regcache, regno);
   else
     {
-      for (r = 0; r < FP0_REGNUM; r++)
-       store_register (r);
-      i387_fill_fsave ((char *) &npx, -1);
+      for (r = 0; r < gdbarch_fp0_regnum (get_regcache_arch (regcache)); r++)
+       store_register (regcache, r);
+      i387_collect_fsave (regcache, -1, &npx);
     }
 }
 
 static void
-go32_prepare_to_store (void)
+go32_prepare_to_store (struct regcache *regcache)
 {
 }
 
 static int
-go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+go32_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int write,
                  struct mem_attrib *attrib, struct target_ops *target)
 {
   if (write)
@@ -556,11 +564,13 @@ go32_files_info (struct target_ops *target)
 }
 
 static void
-go32_stop (void)
+go32_stop (ptid_t ptid)
 {
   normal_stop ();
   cleanup_client ();
+  ptid = inferior_ptid;
   inferior_ptid = null_ptid;
+  delete_thread_silent (ptid);
   prog_has_started = 0;
 }
 
@@ -570,11 +580,13 @@ go32_kill_inferior (void)
   redir_cmdline_delete (&child_cmd);
   resume_signal = -1;
   resume_is_step = 0;
+  if (!ptid_equal (inferior_ptid, null_ptid))
+    delete_thread_silent (inferior_ptid);
   unpush_target (&go32_ops);
 }
 
 static void
-go32_create_inferior (char *exec_file, char *args, char **env)
+go32_create_inferior (char *exec_file, char *args, char **env, int from_tty)
 {
   extern char **environ;
   jmp_buf start_state;
@@ -589,7 +601,7 @@ go32_create_inferior (char *exec_file, char *args, char **env)
 
   if (prog_has_started)
     {
-      go32_stop ();
+      go32_stop (inferior_ptid);
       go32_kill_inferior ();
     }
   resume_signal = -1;
@@ -602,7 +614,7 @@ go32_create_inferior (char *exec_file, char *args, char **env)
   /* Init command line storage.  */
   if (redir_debug_init (&child_cmd) == -1)
     internal_error (__FILE__, __LINE__,
-                   "Cannot allocate redirection storage: not enough memory.\n");
+                   _("Cannot allocate redirection storage: not enough memory.\n"));
 
   /* Parse the command line and create redirections.  */
   if (strpbrk (args, "<>"))
@@ -610,7 +622,7 @@ go32_create_inferior (char *exec_file, char *args, char **env)
       if (redir_cmdline_parse (args, &child_cmd) == 0)
        args = child_cmd.command;
       else
-       error ("Syntax error in command line.");
+       error (_("Syntax error in command line."));
     }
   else
     child_cmd.command = xstrdup (args);
@@ -619,7 +631,7 @@ go32_create_inferior (char *exec_file, char *args, char **env)
   /* v2loadimage passes command lines via DOS memory, so it cannot
      possibly handle commands longer than 1MB.  */
   if (cmdlen > 1024*1024)
-    error ("Command line too long.");
+    error (_("Command line too long."));
 
   cmdline = xmalloc (cmdlen + 4);
   strcpy (cmdline + 1, args);
@@ -651,15 +663,19 @@ go32_create_inferior (char *exec_file, char *args, char **env)
 #endif
 
   inferior_ptid = pid_to_ptid (SOME_PID);
+  add_inferior_silent (SOME_PID);
+
   push_target (&go32_ops);
+
+  add_thread_silent (inferior_ptid);
+
   clear_proceed_status ();
   insert_breakpoints ();
-  proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
   prog_has_started = 1;
 }
 
 static void
-go32_mourn_inferior (void)
+go32_mourn_inferior (struct target_ops *ops)
 {
   /* We need to make sure all the breakpoint enable bits in the DR7
      register are reset when the inferior exits.  Otherwise, if they
@@ -693,7 +709,7 @@ go32_set_dr (int i, CORE_ADDR addr)
 {
   if (i < 0 || i > 3)
     internal_error (__FILE__, __LINE__, 
-                   "Invalid register %d in go32_set_dr.\n", i);
+                   _("Invalid register %d in go32_set_dr.\n"), i);
   D_REGS[i] = addr;
 }
 
@@ -803,8 +819,8 @@ go32_terminal_inferior (void)
   if (redir_to_child (&child_cmd) == -1)
   {
     redir_to_debugger (&child_cmd);
-    error ("Cannot redirect standard handles for program: %s.",
-          strerror (errno));
+    error (_("Cannot redirect standard handles for program: %s."),
+          safe_strerror (errno));
   }
   /* set the console device of the inferior to whatever mode
      (raw or cooked) we found it last time */
@@ -837,12 +853,26 @@ go32_terminal_ours (void)
     if (redir_to_debugger (&child_cmd) == -1)
     {
       redir_to_child (&child_cmd);
-      error ("Cannot redirect standard handles for debugger: %s.",
-            strerror (errno));
+      error (_("Cannot redirect standard handles for debugger: %s."),
+            safe_strerror (errno));
     }
   }
 }
 
+static int
+go32_thread_alive (ptid_t ptid)
+{
+  return 1;
+}
+
+static char *
+go32_pid_to_str (ptid_t ptid)
+{
+  static char buf[64];
+  xsnprintf (buf, sizeof buf, "Thread <main>");
+  return buf;
+}
+
 static void
 init_go32_ops (void)
 {
@@ -859,7 +889,7 @@ init_go32_ops (void)
   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.to_xfer_memory = go32_xfer_memory;
+  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;
@@ -873,6 +903,8 @@ init_go32_ops (void)
   go32_ops.to_mourn_inferior = go32_mourn_inferior;
   go32_ops.to_can_run = go32_can_run;
   go32_ops.to_stop = go32_stop;
+  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 = 1;
   go32_ops.to_has_memory = 1;
@@ -888,10 +920,13 @@ init_go32_ops (void)
   /* 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");
+                   _("Cannot allocate redirection storage: not enough memory.\n"));
 
   /* We are always processing GCC-compiled programs.  */
   processing_gcc_compilation = 2;
+
+  /* Override the default name of the GDB init file.  */
+  strcpy (gdbinit, "gdb.ini");
 }
 
 unsigned short windows_major, windows_minor;
@@ -1255,30 +1290,30 @@ go32_sysinfo (char *arg, int from_tty)
 }
 
 struct seg_descr {
-  unsigned short limit0          __attribute__((packed));
-  unsigned short base0           __attribute__((packed));
-  unsigned char  base1           __attribute__((packed));
-  unsigned       stype:5         __attribute__((packed));
-  unsigned       dpl:2           __attribute__((packed));
-  unsigned       present:1       __attribute__((packed));
-  unsigned       limit1:4        __attribute__((packed));
-  unsigned       available:1     __attribute__((packed));
-  unsigned       dummy:1         __attribute__((packed));
-  unsigned       bit32:1         __attribute__((packed));
-  unsigned       page_granular:1 __attribute__((packed));
-  unsigned char  base2           __attribute__((packed));
-};
+  unsigned short limit0;
+  unsigned short base0;
+  unsigned char  base1;
+  unsigned       stype:5;
+  unsigned       dpl:2;
+  unsigned       present:1;
+  unsigned       limit1:4;
+  unsigned       available:1;
+  unsigned       dummy:1;
+  unsigned       bit32:1;
+  unsigned       page_granular:1;
+  unsigned char  base2;
+} __attribute__ ((packed));
 
 struct gate_descr {
-  unsigned short offset0         __attribute__((packed));
-  unsigned short selector        __attribute__((packed));
-  unsigned       param_count:5   __attribute__((packed));
-  unsigned       dummy:3         __attribute__((packed));
-  unsigned       stype:5         __attribute__((packed));
-  unsigned       dpl:2           __attribute__((packed));
-  unsigned       present:1       __attribute__((packed));
-  unsigned short offset1         __attribute__((packed));
-};
+  unsigned short offset0;
+  unsigned short selector;
+  unsigned       param_count:5;
+  unsigned       dummy:3;
+  unsigned       stype:5;
+  unsigned       dpl:2;
+  unsigned       present:1;
+  unsigned short offset1;
+} __attribute__ ((packed));
 
 /* Read LEN bytes starting at logical address ADDR, and put the result
    into DEST.  Return 1 if success, zero if not.  */
@@ -1515,7 +1550,7 @@ go32_sldt (char *arg, int from_tty)
          if (ldt_entry < 0
              || (ldt_entry & 4) == 0
              || (ldt_entry & 3) != (cpl & 3))
-           error ("Invalid LDT entry 0x%03x.", ldt_entry);
+           error (_("Invalid LDT entry 0x%03lx."), (unsigned long)ldt_entry);
        }
     }
 
@@ -1553,8 +1588,8 @@ go32_sldt (char *arg, int from_tty)
       if (ldt_entry >= 0)
        {
          if (ldt_entry > limit)
-           error ("Invalid LDT entry %#x: outside valid limits [0..%#x]",
-                  ldt_entry, limit);
+           error (_("Invalid LDT entry %#lx: outside valid limits [0..%#x]"),
+                  (unsigned long)ldt_entry, limit);
 
          display_descriptor (ldt_descr.stype, base, ldt_entry / 8, 1);
        }
@@ -1584,8 +1619,8 @@ go32_sgdt (char *arg, int from_tty)
        {
          gdt_entry = parse_and_eval_long (arg);
          if (gdt_entry < 0 || (gdt_entry & 7) != 0)
-           error ("Invalid GDT entry 0x%03x: not an integral multiple of 8.",
-                  gdt_entry);
+           error (_("Invalid GDT entry 0x%03lx: not an integral multiple of 8."),
+                  (unsigned long)gdt_entry);
        }
     }
 
@@ -1595,8 +1630,8 @@ go32_sgdt (char *arg, int from_tty)
   if (gdt_entry >= 0)
     {
       if (gdt_entry > gdtr.limit)
-       error ("Invalid GDT entry %#x: outside valid limits [0..%#x]",
-              gdt_entry, gdtr.limit);
+       error (_("Invalid GDT entry %#lx: outside valid limits [0..%#x]"),
+              (unsigned long)gdt_entry, gdtr.limit);
 
       display_descriptor (0, gdtr.base, gdt_entry / 8, 1);
     }
@@ -1625,7 +1660,7 @@ go32_sidt (char *arg, int from_tty)
        {
          idt_entry = parse_and_eval_long (arg);
          if (idt_entry < 0)
-           error ("Invalid (negative) IDT entry %d.", idt_entry);
+           error (_("Invalid (negative) IDT entry %ld."), idt_entry);
        }
     }
 
@@ -1637,8 +1672,8 @@ go32_sidt (char *arg, int from_tty)
   if (idt_entry >= 0)
     {
       if (idt_entry > idtr.limit)
-       error ("Invalid IDT entry %#x: outside valid limits [0..%#x]",
-              idt_entry, idtr.limit);
+       error (_("Invalid IDT entry %#lx: outside valid limits [0..%#x]"),
+              (unsigned long)idt_entry, idtr.limit);
 
       display_descriptor (1, idtr.base, idt_entry, 1);
     }
@@ -1796,7 +1831,7 @@ go32_pde (char *arg, int from_tty)
        {
          pde_idx = parse_and_eval_long (arg);
          if (pde_idx < 0 || pde_idx >= 1024)
-           error ("Entry %ld is outside valid limits [0..1023].", pde_idx);
+           error (_("Entry %ld is outside valid limits [0..1023]."), pde_idx);
        }
     }
 
@@ -1834,7 +1869,7 @@ display_page_table (long n, int force)
 static void
 go32_pte (char *arg, int from_tty)
 {
-  long pde_idx = -1, i;
+  long pde_idx = -1L, i;
 
   if (arg && *arg)
     {
@@ -1845,7 +1880,7 @@ go32_pte (char *arg, int from_tty)
        {
          pde_idx = parse_and_eval_long (arg);
          if (pde_idx < 0 || pde_idx >= 1024)
-           error ("Entry %d is outside valid limits [0..1023].", pde_idx);
+           error (_("Entry %ld is outside valid limits [0..1023]."), pde_idx);
        }
     }
 
@@ -1873,7 +1908,7 @@ go32_pte_for_address (char *arg, int from_tty)
        addr = parse_and_eval_address (arg);
     }
   if (!addr)
-    error_no_arg ("linear address");
+    error_no_arg (_("linear address"));
 
   pdbr = get_cr3 ();
   if (!pdbr)
@@ -1904,43 +1939,43 @@ _initialize_go32_nat (void)
   init_go32_ops ();
   add_target (&go32_ops);
 
-  add_prefix_cmd ("dos", class_info, go32_info_dos_command,
-                 "Print information specific to DJGPP (aka MS-DOS) debugging.",
+  add_prefix_cmd ("dos", class_info, go32_info_dos_command, _("\
+Print information specific to DJGPP (aka MS-DOS) debugging."),
                  &info_dos_cmdlist, "info dos ", 0, &infolist);
 
-  add_cmd ("sysinfo", class_info, go32_sysinfo,
-           "Display information about the target system, including CPU, OS, DPMI, etc.",
+  add_cmd ("sysinfo", class_info, go32_sysinfo, _("\
+Display information about the target system, including CPU, OS, DPMI, etc."),
           &info_dos_cmdlist);
-  add_cmd ("ldt", class_info, go32_sldt,
-          "Display entries in the LDT (Local Descriptor Table).\n"
-          "Entry number (an expression) as an argument means display only that entry.",
+  add_cmd ("ldt", class_info, go32_sldt, _("\
+Display entries in the LDT (Local Descriptor Table).\n\
+Entry number (an expression) as an argument means display only that entry."),
           &info_dos_cmdlist);
-  add_cmd ("gdt", class_info, go32_sgdt,
-          "Display entries in the GDT (Global Descriptor Table).\n"
-          "Entry number (an expression) as an argument means display only that entry.",
+  add_cmd ("gdt", class_info, go32_sgdt, _("\
+Display entries in the GDT (Global Descriptor Table).\n\
+Entry number (an expression) as an argument means display only that entry."),
           &info_dos_cmdlist);
-  add_cmd ("idt", class_info, go32_sidt,
-          "Display entries in the IDT (Interrupt Descriptor Table).\n"
-          "Entry number (an expression) as an argument means display only that entry.",
+  add_cmd ("idt", class_info, go32_sidt, _("\
+Display entries in the IDT (Interrupt Descriptor Table).\n\
+Entry number (an expression) as an argument means display only that entry."),
           &info_dos_cmdlist);
-  add_cmd ("pde", class_info, go32_pde,
-          "Display entries in the Page Directory.\n"
-          "Entry number (an expression) as an argument means display only that entry.",
+  add_cmd ("pde", class_info, go32_pde, _("\
+Display entries in the Page Directory.\n\
+Entry number (an expression) as an argument means display only that entry."),
           &info_dos_cmdlist);
-  add_cmd ("pte", class_info, go32_pte,
-          "Display entries in Page Tables.\n"
-          "Entry number (an expression) as an argument means display only entries\n"
-          "from the Page Table pointed to by the specified Page Directory entry.",
+  add_cmd ("pte", class_info, go32_pte, _("\
+Display entries in Page Tables.\n\
+Entry number (an expression) as an argument means display only entries\n\
+from the Page Table pointed to by the specified Page Directory entry."),
           &info_dos_cmdlist);
-  add_cmd ("address-pte", class_info, go32_pte_for_address,
-          "Display a Page Table entry for a linear address.\n"
-          "The address argument must be a linear address, after adding to\n"
-          "it the base address of the appropriate segment.\n"
-          "The base address of variables and functions in the debuggee's data\n"
-          "or code segment is stored in the variable __djgpp_base_address,\n"
-          "so use `__djgpp_base_address + (char *)&var' as the argument.\n"
-          "For other segments, look up their base address in the output of\n"
-          "the `info dos ldt' command.",
+  add_cmd ("address-pte", class_info, go32_pte_for_address, _("\
+Display a Page Table entry for a linear address.\n\
+The address argument must be a linear address, after adding to\n\
+it the base address of the appropriate segment.\n\
+The base address of variables and functions in the debuggee's data\n\
+or code segment is stored in the variable __djgpp_base_address,\n\
+so use `__djgpp_base_address + (char *)&var' as the argument.\n\
+For other segments, look up their base address in the output of\n\
+the `info dos ldt' command."),
           &info_dos_cmdlist);
 }
 
This page took 0.033625 seconds and 4 git commands to generate.