This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[rfc] 16 bit real-mode for the i386


Hello,

The attached modifies i386-tdep.c so that there is a ``set i386 real-mode'' command (doco to go).

When real-mode is enabled, GDB computes the ``20 bit'' ``stop address'' (aka PC but not to be confused with $pc ... :-) from both the $cs and $pc registers. That way, core GDB sees a cannonical PC address that (regardless of $cs) will match a ``20 bit'' breakpoint address.

Thoughts?

I'm desperatly trying to come up with a test-case mind. This is a rewrite of an old old patch (that hacked breakpoint.c) and the original testcase has been lost :-(

Andrew
2002-08-29  Andrew Cagney  <cagney@redhat.com>

	* i386-tdep.h (CS_REGNUM): Define.
	* i386-tdep.c (_initialize_i386_tdep): Add `set/show i386
	real-mode' command.
	(i386_write_pc): New function.
	(i386_read_pc): New function.
	(i386_gdbarch_init): Set read_pc and write_pc.
	(set_i386_cmd): New function.
	(show_i386_cmd): New function.

Index: i386-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.c,v
retrieving revision 1.85
diff -u -r1.85 i386-tdep.c
--- i386-tdep.c	26 Aug 2002 18:35:25 -0000	1.85
+++ i386-tdep.c	29 Aug 2002 20:22:12 -0000
@@ -1223,6 +1223,40 @@
      to the extended floating-point format used by the FPU.  */
   convert_typed_floating (from, type, to, builtin_type_i387_ext);
 }
+
+/* The i386 has a number of addressing modes -- in ``real mode'', a
+   text address is computed using the CS and the PC.  The below
+   performs this computation so that GDB sees a cannonical ``stop
+   address'' (PC).  The breakpoint code needs this so that it can
+   correctly match the ``stop address'' against the breakpoint
+   address..  The ia32 manual also talks about optionally truncating
+   an address to 20 bits.  Take the easy option - don't truncate.  */
+
+static int i386_real_mode_p;
+
+static CORE_ADDR
+i386_read_pc (ptid_t ptid)
+{
+  CORE_ADDR pc = read_register_pid (PC_REGNUM, ptid);
+  if (i386_real_mode_p)
+    {
+      CORE_ADDR cs = read_register_pid (CS_REGNUM, ptid);
+      pc = pc + (cs << 4);
+    }
+  return pc;
+}
+
+static void
+i386_write_pc (CORE_ADDR pc, ptid_t ptid)
+{
+  if (i386_real_mode_p)
+    {
+      CORE_ADDR cs = read_register_pid (CS_REGNUM, ptid);
+      pc = pc - (cs << 4);
+    }
+  write_register_pid (PC_REGNUM, pc, ptid);
+}
+
      
 
 #ifdef STATIC_TRANSFORM_NAME
@@ -1474,6 +1508,8 @@
   set_gdbarch_pc_regnum (gdbarch, 8);
   set_gdbarch_ps_regnum (gdbarch, 9);
   set_gdbarch_fp0_regnum (gdbarch, 16);
+  set_gdbarch_read_pc (gdbarch, i386_read_pc);
+  set_gdbarch_write_pc (gdbarch, i386_write_pc);
 
   /* Use the "default" register numbering scheme for stabs and COFF.  */
   set_gdbarch_stab_reg_to_regnum (gdbarch, i386_stab_reg_to_regnum);
@@ -1596,9 +1632,37 @@
 /* Provide a prototype to silence -Wmissing-prototypes.  */
 void _initialize_i386_tdep (void);
 
+/* Dummy function.  */
+static void
+set_i386_cmd (char *args, int from_tty)
+{
+}
+
+static void
+show_i386_cmd (char *args, int from_tty)
+{
+}
+
+
 void
 _initialize_i386_tdep (void)
 {
+  static struct cmd_list_element *set_i386_cmdlist;
+  static struct cmd_list_element *show_i386_cmdlist;
+  struct cmd_list_element *tmpcmd;
+
+  /* Add an i386 set/show prefix.  */
+  add_prefix_cmd ("i386", class_maintenance, set_i386_cmd, "\
+Set i386 specific variables\n\
+Configure various i386 specific variables such as real-mode",
+		  &set_i386_cmdlist, "set i386 ",
+		  0/*allow-unknown*/, &setlist);
+  add_prefix_cmd ("i386", class_maintenance, show_i386_cmd, "\
+Show i386 specific variables\n\
+Configure various i386 specific variables such as real-mode",
+		  &show_i386_cmdlist, "show i386 ",
+		  0/*allow-unknown*/, &showlist);
+
   register_gdbarch_init (bfd_arch_i386, i386_gdbarch_init);
 
   tm_print_insn = gdb_print_insn_i386;
@@ -1643,4 +1707,11 @@
 			  i386_go32_init_abi);
   gdbarch_register_osabi (bfd_arch_i386, GDB_OSABI_NETWARE,
 			  i386_nw_init_abi);
+
+  /* Add real-mode.  */
+  add_setshow_boolean_cmd ("real-mode", no_class, &i386_real_mode_p,"\
+Set real mode (16-bit operands/addresses) operation.","\
+Show real mode (16-bit operands/addresses) operation.",
+			   NULL, NULL, &set_i386_cmdlist, &show_i386_cmdlist);
+
 }
Index: i386-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.h,v
retrieving revision 1.13
diff -u -r1.13 i386-tdep.h
--- i386-tdep.h	20 Aug 2002 17:59:50 -0000	1.13
+++ i386-tdep.h	29 Aug 2002 20:22:12 -0000
@@ -77,6 +77,11 @@
   int sc_sp_offset;
 };
 
+/* Code segment register.  */
+
+#define CS_REGNUM 10
+
+
 /* Floating-point registers.  */
 
 #define FPU_REG_RAW_SIZE 10

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]