Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Hui Zhu <teawater@gmail.com>
To: Michael Snyder <msnyder@vmware.com>,
	Daniel Jacobowitz <dan@codesourcery.com>
Cc: gdb-patches ml <gdb-patches@sourceware.org>,
	"H.J. Lu" <hjl.tools@gmail.com>
Subject: Re: [RFA 3/5] Prec: x86 segment register support: target
Date: Mon, 22 Mar 2010 14:03:00 -0000	[thread overview]
Message-ID: <daef60381003220702w1198e4ddqaae877ffeec51606@mail.gmail.com> (raw)
In-Reply-To: <20100316200424.GA29097@caradoc.them.org>

[-- Attachment #1: Type: text/plain, Size: 2409 bytes --]

Thanks Michael and Daniel.

I make a patch to add base of segments registers to x86-32:
(gdb) info reg
eax            0xffffd514	-10988
ecx            0x1eda96c5	517641925
edx            0x1	1
ebx            0xf7fb1ff4	-134537228
esp            0xffffd488	0xffffd488
ebp            0xffffd488	0xffffd488
esi            0x8048510	134513936
edi            0x80483d0	134513616
eip            0x8048487	0x8048487 <main+3>
eflags         0x246	[ PF ZF IF ]
cs             0x23	35
ss             0x2b	43
ds             0x2b	43
es             0x2b	43
fs             0x0	0
gs             0x63	99
cs_base        0x0	0
ss_base        0x0	0
ds_base        0x0	0
es_base        0x0	0
fs_base        0x0	0
gs_base        0xf7e528d0	-135976752

I try it in x86-32 pc and 32bit code in x86-64.  It works OK.

Please help me review it.

Best regards,
Hui

2010-03-22  Hui Zhu  <teawater@gmail.com>

	* features/i386/32bit-linux.xml (org.gnu.gdb.i386.linux): Add
	cs_base, ss_base, ds_base, es_base, fs_base and gs_base.
	* i386-tdep.h (i386_segment_base_regnum): New enum.
	* amd64-linux-nat.c (GDT_ENTRY_TLS_MIN,
	GDT_ENTRY_TLS_MAX): New marco.
	(ps_get_thread_area): New extern.
	(amd64_linux_fetch_inferior_registers): Add
	code to get 32 bits segment registers base.
	* i386-linux-nat.c (GDT_ENTRY_TLS_ENTRIES,
	GDT_ENTRY_TLS_MIN,
	GDT_ENTRY_TLS_MAX): New marco.
	(ps_get_thread_area): New extern.
	(i386_linux_fetch_inferior_registers): Add
	code to get segment registers base.

On Wed, Mar 17, 2010 at 04:04, Daniel Jacobowitz <dan@codesourcery.com> wrote:
> On Tue, Mar 16, 2010 at 11:12:49AM -0700, Michael Snyder wrote:
>> However, isn't target.c the wrong place for this function?
>> Wouldn't it belong better in the gdbarch?  It is architecture-
>> specific, if I understand correctly.
>>
>> That is, this will be the same between i386-ptrace and i386-remote,
>> but different between i386-remote and (say) mips-remote.
>
> IMO, these should simply be added as new registers.  Since the name
> $gs is already taken, why not add a $gs_base register?
>
> H.J. Lu has recently converted the i386 target to use target
> descriptions; it should be easy to add new registers now.
> They could go in 32bit-linux.xml or in some other file that could be
> shared among OS's.  H.J. may have some more ideas.
>
> --
> Daniel Jacobowitz
> CodeSourcery
>

[-- Attachment #2: add-segment-base.txt --]
[-- Type: text/plain, Size: 5295 bytes --]

---
 amd64-linux-nat.c             |   33 +++++++++++++++++++++++++++++++++
 features/i386/32bit-linux.xml |    6 ++++++
 features/i386/i386-linux.c    |    6 ++++++
 i386-linux-nat.c              |   34 ++++++++++++++++++++++++++++++++++
 i386-tdep.h                   |   10 ++++++++++
 5 files changed, 89 insertions(+)

--- a/amd64-linux-nat.c
+++ b/amd64-linux-nat.c
@@ -155,6 +155,12 @@ fill_fpregset (const struct regcache *re
    this for all registers (including the floating point and SSE
    registers).  */
 
+#define GDT_ENTRY_TLS_MIN 12
+#define GDT_ENTRY_TLS_MAX 14
+
+extern ps_err_e ps_get_thread_area (const struct ps_prochandle *ph,
+		                    lwpid_t lwpid, int idx, void **base);
+
 static void
 amd64_linux_fetch_inferior_registers (struct target_ops *ops,
 				      struct regcache *regcache, int regnum)
@@ -188,6 +194,33 @@ amd64_linux_fetch_inferior_registers (st
 
       amd64_supply_fxsave (regcache, -1, &fpregs);
     }
+
+  if (gdbarch_ptr_bit (gdbarch) == 32
+      && regnum >= I386_CS_BASE_REGNUM && regnum <= I386_GS_BASE_REGNUM)
+    {
+      ULONGEST idx;
+      int base;
+
+      /* Get the idx.  */
+      regcache_raw_read_unsigned (regcache,
+                                  regnum - I386_CS_BASE_REGNUM + I386_CS_REGNUM,
+				  &idx);
+      idx >>= 3;
+
+      /* The base will be 0 if the idx is not TLS.  */
+      if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
+        {
+          regcache_raw_supply (regcache, regnum, NULL);
+          return;
+        }
+
+      /* Get the base.  */
+      if (ps_get_thread_area (NULL, tid, idx, (void *)&base) == PS_ERR)
+        perror_with_name (_("Couldn't get registers"));
+
+      regcache_raw_supply (regcache, regnum, &base);
+      return;
+    }
 }
 
 /* Store register REGNUM back into the child process.  If REGNUM is
--- a/features/i386/32bit-linux.xml
+++ b/features/i386/32bit-linux.xml
@@ -8,4 +8,10 @@
 <!DOCTYPE feature SYSTEM "gdb-target.dtd">
 <feature name="org.gnu.gdb.i386.linux">
   <reg name="orig_eax" bitsize="32" type="int" regnum="41"/>
+  <reg name="cs_base" bitsize="32" type="int" regnum="42"/>
+  <reg name="ss_base" bitsize="32" type="int" regnum="43"/>
+  <reg name="ds_base" bitsize="32" type="int" regnum="44"/>
+  <reg name="es_base" bitsize="32" type="int" regnum="45"/>
+  <reg name="fs_base" bitsize="32" type="int" regnum="46"/>
+  <reg name="gs_base" bitsize="32" type="int" regnum="47"/>
 </feature>
--- a/features/i386/i386-linux.c
+++ b/features/i386/i386-linux.c
@@ -71,6 +71,12 @@ initialize_tdesc_i386_linux (void)
 
   feature = tdesc_create_feature (result, "org.gnu.gdb.i386.linux");
   tdesc_create_reg (feature, "orig_eax", 41, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "cs_base", 42, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "ss_base", 43, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "ds_base", 44, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "es_base", 45, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "fs_base", 46, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "gs_base", 47, 1, NULL, 32, "int");
 
   feature = tdesc_create_feature (result, "org.gnu.gdb.i386.sse");
   field_type = tdesc_named_type (feature, "ieee_single");
--- a/i386-linux-nat.c
+++ b/i386-linux-nat.c
@@ -450,6 +450,13 @@ static int store_fpxregs (const struct r
    this for all registers (including the floating point and SSE
    registers).  */
 
+#define GDT_ENTRY_TLS_ENTRIES	3
+#define GDT_ENTRY_TLS_MIN	6
+#define GDT_ENTRY_TLS_MAX 	(GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1)
+
+extern ps_err_e ps_get_thread_area (const struct ps_prochandle *ph,
+		                    lwpid_t lwpid, int idx, void **base);
+
 static void
 i386_linux_fetch_inferior_registers (struct target_ops *ops,
 				     struct regcache *regcache, int regno)
@@ -516,6 +523,33 @@ i386_linux_fetch_inferior_registers (str
       return;
     }
 
+  /* Get the base of segment registers.  */
+  if (regno >= I386_CS_BASE_REGNUM && regno <= I386_GS_BASE_REGNUM)
+    {
+      ULONGEST idx;
+      int base;
+
+      /* Get the idx.  */
+      regcache_raw_read_unsigned (regcache,
+                                  regno - I386_CS_BASE_REGNUM + I386_CS_REGNUM,
+				  &idx);
+      idx >>= 3;
+
+      /* The base will be 0 if the idx is not TLS.  */
+      if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
+        {
+          regcache_raw_supply (regcache, regno, NULL);
+          return;
+        }
+
+      /* Get the base.  */
+      if (ps_get_thread_area (NULL, tid, idx, (void *)&base) == PS_ERR)
+        perror_with_name (_("Couldn't get registers"));
+
+      regcache_raw_supply (regcache, regno, &base);
+      return;
+    }
+
   internal_error (__FILE__, __LINE__,
 		  _("Got request for bad register number %d."), regno);
 }
--- a/i386-tdep.h
+++ b/i386-tdep.h
@@ -231,6 +231,16 @@ enum i386_regnum
   I386_MXCSR_REGNUM = 40	/* %mxcsr */ 
 };
 
+enum i386_segment_base_regnum
+{
+  I386_CS_BASE_REGNUM = 42,	/* %cs_base */
+  I386_SS_BASE_REGNUM,		/* %ss_base */
+  I386_DS_BASE_REGNUM,		/* %ds_base */
+  I386_ES_BASE_REGNUM,		/* %es_base */
+  I386_FS_BASE_REGNUM,		/* %fs_base */
+  I386_GS_BASE_REGNUM,		/* %gs_base */
+};
+
 /* Register numbers of RECORD_REGMAP.  */
 
 enum record_i386_regnum

  reply	other threads:[~2010-03-22 14:03 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-03-16 16:53 Hui Zhu
2010-03-16 18:12 ` Michael Snyder
2010-03-16 20:04   ` Daniel Jacobowitz
2010-03-22 14:03     ` Hui Zhu [this message]
2010-03-22 14:35       ` H.J. Lu
2010-03-22 14:44         ` Hui Zhu
2010-03-22 15:05         ` Mark Kettenis
2010-03-22 14:35       ` Mark Kettenis
2010-03-22 14:45         ` Hui Zhu
2010-03-22 14:53         ` Daniel Jacobowitz
2010-03-22 18:04           ` Eli Zaretskii
2010-03-22 18:14             ` Doug Evans
2010-03-22 16:03         ` Doug Evans

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=daef60381003220702w1198e4ddqaae877ffeec51606@mail.gmail.com \
    --to=teawater@gmail.com \
    --cc=dan@codesourcery.com \
    --cc=gdb-patches@sourceware.org \
    --cc=hjl.tools@gmail.com \
    --cc=msnyder@vmware.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox