/* Native debugging support for Intel x86 running DJGPP.
- Copyright (C) 1997-2016 Free Software Foundation, Inc.
+ Copyright (C) 1997-2019 Free Software Foundation, Inc.
Written by Robert Hoehne.
This file is part of GDB.
#include "inferior.h"
#include "infrun.h"
#include "gdbthread.h"
-#include "gdb_wait.h"
+#include "gdbsupport/gdb_wait.h"
#include "gdbcore.h"
#include "command.h"
#include "gdbcmd.h"
#include "floatformat.h"
-#include "buildsym.h"
+#include "buildsym-legacy.h"
#include "i387-tdep.h"
#include "i386-tdep.h"
#include "nat/x86-cpuid.h"
#define SOME_PID 42
static int prog_has_started = 0;
-static void go32_mourn_inferior (struct target_ops *ops);
#define r_ofs(x) (offsetof(TSS,x))
{GDB_SIGNAL_LAST, -1}
};
-static void
-go32_attach (struct target_ops *ops, const char *args, int from_tty)
+/* The go32 target. */
+
+struct go32_nat_target final : public x86_nat_target<inf_child_target>
+{
+ void attach (const char *, int) override;
+
+ void resume (ptid_t, int, enum gdb_signal) override;
+
+ ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+
+ void fetch_registers (struct regcache *, int) override;
+ void store_registers (struct regcache *, int) override;
+
+ enum target_xfer_status xfer_partial (enum target_object object,
+ const char *annex,
+ gdb_byte *readbuf,
+ const gdb_byte *writebuf,
+ ULONGEST offset, ULONGEST len,
+ ULONGEST *xfered_len) override;
+
+ void files_info () override;
+
+ void terminal_init () override;
+
+ void terminal_inferior () override;
+
+ void terminal_ours_for_output () override;
+
+ void terminal_ours () override;
+
+ void terminal_info (const char *, int) override;
+
+ void pass_ctrlc () override;
+
+ void kill () override;
+
+ void create_inferior (const char *, const std::string &,
+ char **, int) override;
+
+ void mourn_inferior () override;
+
+ bool thread_alive (ptid_t ptid) override;
+
+ std::string pid_to_str (ptid_t) override;
+};
+
+static go32_nat_target the_go32_nat_target;
+
+void
+go32_nat_target::attach (const char *args, int from_tty)
{
error (_("\
You cannot attach to a running program on this platform.\n\
static int resume_is_step;
static int resume_signal = -1;
-static void
-go32_resume (struct target_ops *ops,
- ptid_t ptid, int step, enum gdb_signal siggnal)
+void
+go32_nat_target::resume (ptid_t ptid, int step, enum gdb_signal siggnal)
{
int i;
static char child_cwd[FILENAME_MAX];
-static ptid_t
-go32_wait (struct target_ops *ops,
- ptid_t ptid, struct target_waitstatus *status, int options)
+ptid_t
+go32_nat_target::wait (ptid_t ptid, struct target_waitstatus *status,
+ int options)
{
int i;
unsigned char saved_opcode;
}
}
}
- return pid_to_ptid (SOME_PID);
+ return ptid_t (SOME_PID);
}
static void
fetch_register (struct regcache *regcache, int regno)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
if (regno < gdbarch_fp0_regnum (gdbarch))
- regcache_raw_supply (regcache, regno,
- (char *) &a_tss + regno_mapping[regno].tss_ofs);
+ regcache->raw_supply (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);
_("Invalid register no. %d in fetch_register."), regno);
}
-static void
-go32_fetch_registers (struct target_ops *ops,
- struct regcache *regcache, int regno)
+void
+go32_nat_target::fetch_registers (struct regcache *regcache, int regno)
{
if (regno >= 0)
fetch_register (regcache, regno);
else
{
for (regno = 0;
- regno < gdbarch_fp0_regnum (get_regcache_arch (regcache));
+ regno < gdbarch_fp0_regnum (regcache->arch ());
regno++)
fetch_register (regcache, regno);
i387_supply_fsave (regcache, -1, &npx);
static void
store_register (const struct regcache *regcache, int regno)
{
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch *gdbarch = regcache->arch ();
if (regno < gdbarch_fp0_regnum (gdbarch))
- regcache_raw_collect (regcache, regno,
- (char *) &a_tss + regno_mapping[regno].tss_ofs);
+ regcache->raw_collect (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);
_("Invalid register no. %d in store_register."), regno);
}
-static void
-go32_store_registers (struct target_ops *ops,
- struct regcache *regcache, int regno)
+void
+go32_nat_target::store_registers (struct regcache *regcache, int regno)
{
unsigned r;
store_register (regcache, regno);
else
{
- for (r = 0; r < gdbarch_fp0_regnum (get_regcache_arch (regcache)); r++)
+ for (r = 0; r < gdbarch_fp0_regnum (regcache->arch ()); r++)
store_register (regcache, r);
i387_collect_fsave (regcache, -1, &npx);
}
/* 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)
+enum target_xfer_status
+go32_nat_target::xfer_partial (enum target_object object,
+ const char *annex, gdb_byte *readbuf,
+ const gdb_byte *writebuf, ULONGEST offset,
+ ULONGEST len,
+ ULONGEST *xfered_len)
{
switch (object)
{
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);
+ return this->beneath ()->xfer_partial (object, annex,
+ readbuf, writebuf, offset, len,
+ xfered_len);
}
}
static cmdline_t child_cmd; /* Parsed child's command line kept here. */
-static void
-go32_files_info (struct target_ops *target)
+void
+go32_nat_target::files_info ()
{
printf_unfiltered ("You are running a DJGPP V2 program.\n");
}
-static void
-go32_kill_inferior (struct target_ops *ops)
+void
+go32_nat_target::kill_inferior ()
{
- go32_mourn_inferior (ops);
+ mourn_inferior ();
}
-static void
-go32_create_inferior (struct target_ops *ops, char *exec_file,
- char *args, char **env, int from_tty)
+void
+go32_nat_target::create_inferior (const char *exec_file,
+ const std::string &allargs,
+ char **env, int from_tty)
{
extern char **environ;
jmp_buf start_state;
size_t cmdlen;
struct inferior *inf;
int result;
+ const char *args = allargs.c_str ();
/* If no exec file handed to us, get it from the exec-file command -- with
a good, common error message if none is specified. */
save_npx ();
#endif
- inferior_ptid = pid_to_ptid (SOME_PID);
+ inferior_ptid = ptid_t (SOME_PID);
inf = current_inferior ();
inferior_appeared (inf, SOME_PID);
- if (!target_is_pushed (ops))
- push_target (ops);
+ if (!target_is_pushed (this))
+ push_target (this);
add_thread_silent (inferior_ptid);
prog_has_started = 1;
}
-static void
-go32_mourn_inferior (struct target_ops *ops)
+void
+go32_nat_target::mourn_inferior ()
{
ptid_t ptid;
ptid = inferior_ptid;
inferior_ptid = null_ptid;
- delete_thread_silent (ptid);
prog_has_started = 0;
generic_mourn_inferior ();
- inf_child_maybe_unpush_target (ops);
+ maybe_unpush_target ();
}
/* Hardware watchpoint support. */
second call will always see GDB's own cooked terminal. */
static int terminal_is_ours = 1;
-static void
-go32_terminal_init (struct target_ops *self)
+void
+go32_nat_target::terminal_init ()
{
inf_mode_valid = 0; /* Reinitialize, in case they are restarting child. */
terminal_is_ours = 1;
}
-static void
-go32_terminal_info (struct target_ops *self, const char *args, int from_tty)
+void
+go32_nat_target::terminal_info (const char *args, int from_tty)
{
printf_unfiltered ("Inferior's terminal is in %s mode.\n",
!inf_mode_valid
#endif
}
-static void
-go32_terminal_inferior (struct target_ops *self)
+void
+go32_nat_target::terminal_inferior ()
{
/* Redirect standard handles as child wants them. */
errno = 0;
}
}
-static void
-go32_terminal_ours (struct target_ops *self)
+void
+go32_nat_target::terminal_ours ()
{
/* Switch to cooked mode on the gdb terminal and save the inferior
terminal mode to be restored when it is resumed. */
}
}
-static int
-go32_thread_alive (struct target_ops *ops, ptid_t ptid)
+void
+go32_nat_target::pass_ctrlc ()
{
- return !ptid_equal (inferior_ptid, null_ptid);
}
-static char *
-go32_pid_to_str (struct target_ops *ops, ptid_t ptid)
+bool
+go32_nat_target::thread_alive (ptid_t ptid)
{
- return normal_pid_to_str (ptid);
+ return ptid != null_ptid;
}
-/* Create a go32 target. */
-
-static struct target_ops *
-go32_target (void)
+std::string
+go32_nat_target::pid_to_str (ptid_t ptid)
{
- 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 normal_pid_to_str (ptid);
}
/* Return the current DOS codepage number. */
/* Display assorted information about the underlying OS. */
static void
-go32_sysinfo (char *arg, int from_tty)
+go32_sysinfo (const char *arg, int from_tty)
{
static const char test_pattern[] =
"deadbeafdeadbeafdeadbeafdeadbeafdeadbeaf"
/* CPUID with EAX = 1 returns processor signature and features. */
if (cpuid_max >= 1)
{
- static char *brand_name[] = {
+ static const char *brand_name[] = {
"",
" Celeron",
" III",
unsigned brand_idx;
int intel_p = strcmp (cpuid_vendor, "GenuineIntel") == 0;
int amd_p = strcmp (cpuid_vendor, "AuthenticAMD") == 0;
+ int hygon_p = strcmp (cpuid_vendor, "HygonGenuine") == 0;
unsigned cpu_family, cpu_model;
#if 0
}
}
xsnprintf (cpu_string, sizeof (cpu_string), "%s%s Model %d Stepping %d",
- intel_p ? "Pentium" : (amd_p ? "AMD" : "ix86"),
+ intel_p ? "Pentium" : (amd_p ? "AMD" : (hygon_p ? "Hygon" : "ix86")),
cpu_brand, cpu_model, cpuid_eax & 0xf);
printfi_filtered (31, "%s\n", cpu_string);
if (((cpuid_edx & (6 | (0x0d << 23))) != 0)
|| ((cpuid_edx & 1) == 0)
- || (amd_p && (cpuid_edx & (3 << 30)) != 0))
+ || ((amd_p || hygon_p) && (cpuid_edx & (3 << 30)) != 0))
{
puts_filtered ("CPU Features...................");
/* We only list features which might be useful in the DPMI
puts_filtered ("SSE ");
if ((cpuid_edx & (1 << 26)) != 0)
puts_filtered ("SSE2 ");
- if (amd_p)
+ if (amd_p || hygon_p)
{
if ((cpuid_edx & (1 << 31)) != 0)
puts_filtered ("3DNow! ");
}
static void
-go32_sldt (char *arg, int from_tty)
+go32_sldt (const char *arg, int from_tty)
{
struct dtr_reg gdtr;
unsigned short ldtr = 0;
}
static void
-go32_sgdt (char *arg, int from_tty)
+go32_sgdt (const char *arg, int from_tty)
{
struct dtr_reg gdtr;
long gdt_entry = -1L;
}
static void
-go32_sidt (char *arg, int from_tty)
+go32_sidt (const char *arg, int from_tty)
{
struct dtr_reg idtr;
long idt_entry = -1L;
}
static void
-go32_pde (char *arg, int from_tty)
+go32_pde (const char *arg, int from_tty)
{
long pde_idx = -1, i;
}
static void
-go32_pte (char *arg, int from_tty)
+go32_pte (const char *arg, int from_tty)
{
long pde_idx = -1L, i;
}
static void
-go32_pte_for_address (char *arg, int from_tty)
+go32_pte_for_address (const char *arg, int from_tty)
{
CORE_ADDR addr = 0, i;
static struct cmd_list_element *info_dos_cmdlist = NULL;
static void
-go32_info_dos_command (char *args, int from_tty)
+go32_info_dos_command (const char *args, int from_tty)
{
help_list (info_dos_cmdlist, "info dos ", class_info, gdb_stdout);
}
-/* -Wmissing-prototypes */
-extern initialize_file_ftype _initialize_go32_nat;
-
void
_initialize_go32_nat (void)
{
- 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_addr = go32_get_dr;
x86_set_debug_register_length (4);
- x86_use_watchpoints (t);
- add_target (t);
+ add_inf_child_target (&the_go32_nat_target);
/* Initialize child's cwd as empty to be initialized when starting
the child. */