This is the mail archive of the gdb-patches@sourceware.org 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]

Re: PATCH: Enable x86 XML target descriptions


> Date: Sun, 28 Feb 2010 13:15:34 -0800
> From: "H.J. Lu" <hongjiu.lu@intel.com>
> 
> On Mon, Feb 22, 2010 at 01:03:56PM -0800, H.J. Lu wrote:
> > On Thu, Feb 18, 2010 at 03:01:35PM -0800, H.J. Lu wrote:
> > > On Thu, Feb 18, 2010 at 07:34:02AM -0800, H.J. Lu wrote:
> > > > On Wed, Feb 17, 2010 at 09:43:12PM -0800, H.J. Lu wrote:
> > > > > On Wed, Feb 10, 2010 at 12:03:03PM -0800, H.J. Lu wrote:
> > > > > > Hi,
> > > > > > 
> > > > > > This patch enables x86 XML target descriptions.  I used
> > > > > > i386_linux_init_orig_eax to support the old gdbserver which doesn't
> > > > > > have XML target descriptions.
> > > > > > 
> > > > > > The register description processing is handled in i386_gdbarch_init
> > > > > > for 32bit/64bit as well as all ABIs to avoid code duplication and
> > > > > > unnecessary complexity.
> > > > > > 
> > > > > > OK to install?
> > > > > > 
> > > > > 
> > > > > Here is the updated patch. I removed all BFD64 from i386 files.  I
> > > > > renamed I386_NUM_FREGS to I387_NUM_REGS and put it in i387-tdep.h.
> > > > > I use it in amd64-tdep.c.  I added a few fields to gdbarch_tdep so 
> > > > > that I can pass values from xxx_abit_init to i386_gdbarch_init.  OK
> > > > > to install?
> > > > > 
> > > > > Thanks.
> > > > > 
> > > > > 
> > > > 
> > > > A small update. I added I386_MXCSR_REGNUM so that "i387-tdep.h"
> > > > isn't added for amd64-linux-nat.c, amd64-linux-tdep.c and
> > > > i386-linux-tdep.c. OK to install?
> > > > 
> > > 
> > > A small bug fix.  amd64_linux_read_description should return
> > > tdesc_i386_linux for 32bit.
> > > 
> > 
> > Here is the updated patch. I have addressed all issues raised so far
> > as mush as I can.  Any comments/suggestions?
> > 
> 
> Here is the updated patch.  Any comments/suggestions?

Given Daniel's explanation about num_regs and the feature names, this
is ok with me.

> gdb/
> 
> 2010-02-28  H.J. Lu  <hongjiu.lu@intel.com>
> 
> 	* amd64-linux-nat.c (AMD64_LINUX_USER64_CS): New.
> 	(amd64_linux_read_description): Likewise.
> 	(_initialize_amd64_linux_nat): Set to_read_description to
> 	amd64_linux_read_description.
> 
> 	* amd64-linux-tdep.c: Include "features/i386/amd64-linux.c".
> 	(amd64_linux_register_name): Removed.
> 	(amd64_linux_register_type): Likewise.
> 	(amd64_linux_core_read_description): New.
> 	(amd64_linux_init_abi): Set target description to
> 	tdesc_amd64_linux if needed.  Support orig_rax in target
> 	description.  Don't call set_gdbarch_register_name nor
> 	set_gdbarch_register_type.  Call
> 	set_gdbarch_core_read_description.
> 	(_initialize_amd64_linux_tdep): Call
> 	initialize_tdesc_amd64_linux.
> 
> 	* amd64-linux-tdep.h (tdesc_amd64_linux): New.
> 
> 	* amd64-tdep.c:  Include "features/i386/amd64.c".
> 	(amd64_register_names): Removed.
> 	(amd64_register_name): Likewise.
> 	(amd64_register_type): Likewise.
> 	(amd64_init_abi):  Set num_core_regs and register_names.  Set
> 	target description to tdesc_amd64 if needed.  Don't call 
> 	set_gdbarch_register_name nor set_gdbarch_register_type.
> 	(_initialize_amd64_tdep): New.
> 
> 	* i386-linux-nat.c (i386_linux_read_description): New.
> 	(_initialize_i386_linux_nat): Set to_read_description to
> 	i386_linux_read_description.
> 
> 	* i386-linux-tdep.c: Include "features/i386/i386-linux.c".
> 	(i386_linux_register_name): Removed.
> 	(i386_linux_core_read_description): New.
> 	(i386_linux_read_description): Likewise.
> 	(i386_linux_init_abi): Don't call set_gdbarch_register_name.
> 	Set target description to tdesc_i386_linux if needed.  Support
> 	orig_eax.  Set register_reggroup_p.  Call
> 	set_gdbarch_core_read_description.
> 	(_initialize_i386_linux_tdep): Call initialize_tdesc_i386_linux.
> 
> 	* i386-linux-tdep.h (tdesc_i386_linux): New.
> 
> 	* i386-nto-tdep.c (i386nto_regset_id): Replace I386_NUM_FREGS
> 	with I387_NUM_REGS.
> 
> 	* i386-tdep.c: Include "features/i386/i386.c".
> 	(i386_register_names): Make it const.
> 	(i386_mmx_names): Likewise.
> 	(i386_num_register_names): Removed.
> 	(i386_register_name): Likewise.
> 	(i386_eflags_type): Likewise.
> 	(i386_mxcsr_type): Likewise.
> 	(i386_sse_type): Likewise.
> 	(i386_register_type): Likewise.
> 	(i387_ext_type): Call tdesc_find_type instead of arch_float_type.
> 	(i386_pseudo_register_name): New.
> 	(i386_pseudo_register_type): Likewise.
> 	(i386_mmx_type): Make it static.
> 	(i386_gdbarch_init): Check arch.  Replace I386_NUM_FREGS with
> 	I387_NUM_REGS.  Set num_core_regs and register_names.  Don't
> 	call set_gdbarch_register_name nor set_gdbarch_register_type.
> 	Set register_reggroup_p.  Set target description to tdesc_i386
> 	if needed.  Call set_tdesc_pseudo_register_type,
> 	set_tdesc_pseudo_register_name and tdesc_use_registers.
> 	(_initialize_i386_tdep): Call initialize_tdesc_i386.
> 	initialize_tdesc_x86_64.
> 
> 	* i386-tdep.h (gdbarch_tdep): Remove i386_eflags_type,
> 	i386_mxcsr_type and i386_sse_type.  Add num_core_regs,
> 	register_names, tdesc and register_reggroup_p.
> 	(I386_NUM_FREGS): Removed.
> 	(i386_eflags_type): Likewise.
> 	(i386_mxcsr_type): Likewise.
> 	(i386_mmx_type): Likewise.
> 	(i386_sse_type): Likewise.
> 	(i386_register_name): Likewise.
> 	(i386_regnum): Add I386_MXCSR_REGNUM.
> 	(I386_SSE_NUM_REGS): Defined with I386_MXCSR_REGNUM.
> 
> 	* i387-tdep.h (I387_NUM_REGS): New.
> 
> 	* regformats/i386/i386-linux.dat: Generated.
> 	* regformats/i386/i386.dat: Likewise.
> 	* regformats/i386/amd64-linux.dat: Likewise.
> 	* regformats/i386/amd64.dat: Likewise.
> 
> 	* regformats/reg-i386-linux.dat: Removed.
> 	* regformats/reg-i386.dat: Likewise.
> 	* regformats/reg-x86-64-linux.dat: Likewise.
> 	* regformats/reg-x86-64.dat: Likewise.
> 
> gdb/gdbserver/
> 
> 2010-02-28  H.J. Lu  <hongjiu.lu@intel.com>
> 
> 	* Makefile.in (clean): Replace reg-i386.c, reg-x86-64.c,
> 	reg-i386-linux.c and reg-x86-64-linux.c with i386.c, amd64.c,
> 	i386-linux.c and amd64-linux.c.
> 	(reg-i386.o): Removed.
> 	(reg-i386.c): Likewise.
> 	(reg-i386-linux.o): Likewise.
> 	(reg-i386-linux.c): Likewise.
> 	(reg-x86-64.o): Likewise.
> 	(reg-x86-64.c): Likewise.
> 	(reg-x86-64-linux.o): Likewise.
> 	(reg-x86-64-linux.c): Likewise.
> 	(i386.o): New.
> 	(i386.c): Likewise.
> 	(i386-linux.o): Likewise.
> 	(i386-linux.c): Likewise.
> 	(amd64.o): Likewise.
> 	(amd64.c): Likewise.
> 	(amd64-linux.o): Likewise.
> 	(amd64-linux.c): Likewise.
> 
> 	* configure.srv (srv_i386_regobj): New.
> 	(srv_i386_linux_regobj): Likewise.
> 	(srv_amd64_regobj): Likewise.
> 	(srv_amd64_linux_regobj): Likewise.
> 	(srv_i386_32bit_xmlfiles): Likewise.
> 	(srv_i386_64bit_xmlfiles): Likewise.
> 	(srv_i386_xmlfiles): Likewise.
> 	(srv_amd64_xmlfiles): Likewise.
> 	(srv_i386_linux_xmlfiles): Likewise.
> 	(srv_amd64_linux_xmlfiles): Likewise.
> 	(i[34567]86-*-cygwin*): Set srv_regobj to $srv_i386_regobj.  Set
> 	srv_xmlfiles to $srv_i386_xmlfiles.
> 	(i[34567]86-*-mingw32ce*): Likewise.
> 	(i[34567]86-*-mingw*): Likewise.
> 	(i[34567]86-*-nto*): Likewise.
> 	(i[34567]86-*-linux*): Set srv_regobj to $srv_i386_linux_regobj
> 	and $srv_amd64_linux_regobj.  Set srv_xmlfiles to
> 	$srv_i386_linux_xmlfiles and $srv_amd64_linux_xmlfiles.
> 	(x86_64-*-linux*): Likewise.
> 
> 	* linux-x86-low.c (init_registers_x86_64_linux): Removed.
> 	(init_registers_amd64_linux): New.
> 	(x86_arch_setup): Replace init_registers_x86_64_linux with
> 	init_registers_amd64_linux.
> 
> gdb/testsuite/
> 
> 2010-02-28  H.J. Lu  <hongjiu.lu@intel.com>
> 
> 	* gdb.xml/tdesc-regs.exp (architecture): New.  Set it for x86.
> 	(load_description): Set architecture if defined.
> 
> diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
> index 5c9e558..b9d5833 100644
> --- a/gdb/amd64-linux-nat.c
> +++ b/gdb/amd64-linux-nat.c
> @@ -674,6 +674,39 @@ amd64_linux_siginfo_fixup (struct siginfo *native, gdb_byte *inf, int direction)
>      return 0;
>  }
>  
> +/* Get Linux/x86 target description from running target.
> +
> +   Value of CS segment register:
> +     1. 64bit process: 0x33.
> +     2. 32bit process: 0x23.
> + */
> +
> +#define AMD64_LINUX_USER64_CS	0x33
> +
> +static const struct target_desc *
> +amd64_linux_read_description (struct target_ops *ops)
> +{
> +  unsigned long cs;
> +  int tid;
> +
> +  /* GNU/Linux LWP ID's are process ID's.  */
> +  tid = TIDGET (inferior_ptid);
> +  if (tid == 0)
> +    tid = PIDGET (inferior_ptid); /* Not a threaded program.  */
> +
> +  /* Get CS register.  */
> +  errno = 0;
> +  cs = ptrace (PTRACE_PEEKUSER, tid,
> +	       offsetof (struct user_regs_struct, cs), 0);
> +  if (errno != 0)
> +    perror_with_name (_("Couldn't get CS register"));
> +
> +  if (cs == AMD64_LINUX_USER64_CS)
> +    return tdesc_amd64_linux;
> +  else
> +    return tdesc_i386_linux;
> +}
> +
>  /* Provide a prototype to silence -Wmissing-prototypes.  */
>  void _initialize_amd64_linux_nat (void);
>  
> @@ -712,6 +745,8 @@ _initialize_amd64_linux_nat (void)
>    t->to_fetch_registers = amd64_linux_fetch_inferior_registers;
>    t->to_store_registers = amd64_linux_store_inferior_registers;
>  
> +  t->to_read_description = amd64_linux_read_description;
> +
>    /* Register the target.  */
>    linux_nat_add_target (t);
>    linux_nat_set_new_thread (t, amd64_linux_new_thread);
> diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
> index c28eef7..4ad6dc9 100644
> --- a/gdb/amd64-linux-tdep.c
> +++ b/gdb/amd64-linux-tdep.c
> @@ -37,6 +37,8 @@
>  #include "solib-svr4.h"
>  #include "xml-syscall.h"
>  
> +#include "features/i386/amd64-linux.c"
> +
>  /* The syscall's XML filename for i386.  */
>  #define XML_SYSCALL_FILENAME_AMD64 "syscalls/amd64-linux.xml"
>  
> @@ -234,26 +236,6 @@ static int amd64_linux_sc_reg_offset[] =
>    -1				/* %gs */
>  };
>  
> -/* Replacement register functions which know about %orig_rax.  */
> -
> -static const char *
> -amd64_linux_register_name (struct gdbarch *gdbarch, int reg)
> -{
> -  if (reg == AMD64_LINUX_ORIG_RAX_REGNUM)
> -    return "orig_rax";
> -
> -  return amd64_register_name (gdbarch, reg);
> -}
> -
> -static struct type *
> -amd64_linux_register_type (struct gdbarch *gdbarch, int reg)
> -{
> -  if (reg == AMD64_LINUX_ORIG_RAX_REGNUM)
> -    return builtin_type (gdbarch)->builtin_int64;
> -
> -  return amd64_register_type (gdbarch, reg);
> -}
> -
>  static int
>  amd64_linux_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
>  				 struct reggroup *group)
> @@ -1260,10 +1242,32 @@ amd64_linux_record_signal (struct gdbarch *gdbarch,
>    return 0;
>  }
>  
> +/* Get Linux/x86 target description from core dump.  */
> +
> +static const struct target_desc *
> +amd64_linux_core_read_description (struct gdbarch *gdbarch,
> +				  struct target_ops *target,
> +				  bfd *abfd)
> +{
> +  asection *section = bfd_get_section_by_name (abfd, ".reg2");
> +
> +  if (section == NULL)
> +    return NULL;
> +
> +  /* Linux/x86-64.  */
> +  return tdesc_amd64_linux;
> +}
> +
>  static void
>  amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
>  {
>    struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> +  const struct target_desc *tdesc = info.target_desc;
> +  struct tdesc_arch_data *tdesc_data = (void *) info.tdep_info;
> +  const struct tdesc_feature *feature;
> +  int valid_p;
> +
> +  gdb_assert (tdesc_data);
>  
>    tdep->gregset_reg_offset = amd64_linux_gregset_reg_offset;
>    tdep->gregset_num_regs = ARRAY_SIZE (amd64_linux_gregset_reg_offset);
> @@ -1271,6 +1275,23 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
>  
>    amd64_init_abi (info, gdbarch);
>  
> +  /* Reserve a number for orig_rax.  */
> +  set_gdbarch_num_regs (gdbarch, AMD64_LINUX_NUM_REGS);
> +
> +  if (! tdesc_has_registers (tdesc))
> +    tdesc = tdesc_amd64_linux;
> +  tdep->tdesc = tdesc;
> +
> +  feature = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.linux");
> +  if (feature == NULL)
> +    return;
> +
> +  valid_p = tdesc_numbered_register (feature, tdesc_data,
> +				     AMD64_LINUX_ORIG_RAX_REGNUM,
> +				     "orig_rax");
> +  if (!valid_p)
> +    return;
> +
>    tdep->sigtramp_p = amd64_linux_sigtramp_p;
>    tdep->sigcontext_addr = amd64_linux_sigcontext_addr;
>    tdep->sc_reg_offset = amd64_linux_sc_reg_offset;
> @@ -1282,10 +1303,8 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
>  
>    /* Add the %orig_rax register used for syscall restarting.  */
>    set_gdbarch_write_pc (gdbarch, amd64_linux_write_pc);
> -  set_gdbarch_num_regs (gdbarch, AMD64_LINUX_NUM_REGS);
> -  set_gdbarch_register_name (gdbarch, amd64_linux_register_name);
> -  set_gdbarch_register_type (gdbarch, amd64_linux_register_type);
> -  set_gdbarch_register_reggroup_p (gdbarch, amd64_linux_register_reggroup_p);
> +
> +  tdep->register_reggroup_p = amd64_linux_register_reggroup_p;
>  
>    /* Functions for 'catch syscall'.  */
>    set_xml_syscall_file_name (XML_SYSCALL_FILENAME_AMD64);
> @@ -1299,6 +1318,9 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
>    /* GNU/Linux uses SVR4-style shared libraries.  */
>    set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
>  
> +  set_gdbarch_core_read_description (gdbarch,
> +				     amd64_linux_core_read_description);
> +
>    /* Displaced stepping.  */
>    set_gdbarch_displaced_step_copy_insn (gdbarch,
>                                          amd64_displaced_step_copy_insn);
> @@ -1492,4 +1514,7 @@ _initialize_amd64_linux_tdep (void)
>  {
>    gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
>  			  GDB_OSABI_LINUX, amd64_linux_init_abi);
> +
> +  /* Initialize the Linux target description  */
> +  initialize_tdesc_amd64_linux ();
>  }
> diff --git a/gdb/amd64-linux-tdep.h b/gdb/amd64-linux-tdep.h
> index 20a15ca..33316fb 100644
> --- a/gdb/amd64-linux-tdep.h
> +++ b/gdb/amd64-linux-tdep.h
> @@ -31,6 +31,9 @@
>  /* Total number of registers for GNU/Linux.  */
>  #define AMD64_LINUX_NUM_REGS (AMD64_LINUX_ORIG_RAX_REGNUM + 1)
>  
> +/* Linux target description.  */
> +extern struct target_desc *tdesc_amd64_linux;
> +
>  /* Enum that defines the syscall identifiers for amd64 linux.
>     Used for process record/replay, these will be translated into
>     a gdb-canonical set of syscall ids in linux-record.c.  */
> diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
> index 2b15141..0ec60c1 100644
> --- a/gdb/amd64-tdep.c
> +++ b/gdb/amd64-tdep.c
> @@ -42,6 +42,8 @@
>  #include "amd64-tdep.h"
>  #include "i387-tdep.h"
>  
> +#include "features/i386/amd64.c"
> +
>  /* Note that the AMD64 architecture was previously known as x86-64.
>     The latter is (forever) engraved into the canonical system name as
>     returned by config.guess, and used as the name for the AMD64 port
> @@ -83,47 +85,6 @@ static int amd64_dummy_call_integer_regs[] =
>    9				/* %r9 */
>  };
>  
> -/* Return the name of register REGNUM.  */
> -
> -const char *
> -amd64_register_name (struct gdbarch *gdbarch, int regnum)
> -{
> -  if (regnum >= 0 && regnum < AMD64_NUM_REGS)
> -    return amd64_register_names[regnum];
> -
> -  return NULL;
> -}
> -
> -/* Return the GDB type object for the "standard" data type of data in
> -   register REGNUM. */
> -
> -struct type *
> -amd64_register_type (struct gdbarch *gdbarch, int regnum)
> -{
> -  if (regnum >= AMD64_RAX_REGNUM && regnum <= AMD64_RDI_REGNUM)
> -    return builtin_type (gdbarch)->builtin_int64;
> -  if (regnum == AMD64_RBP_REGNUM || regnum == AMD64_RSP_REGNUM)
> -    return builtin_type (gdbarch)->builtin_data_ptr;
> -  if (regnum >= AMD64_R8_REGNUM && regnum <= AMD64_R15_REGNUM)
> -    return builtin_type (gdbarch)->builtin_int64;
> -  if (regnum == AMD64_RIP_REGNUM)
> -    return builtin_type (gdbarch)->builtin_func_ptr;
> -  if (regnum == AMD64_EFLAGS_REGNUM)
> -    return i386_eflags_type (gdbarch);
> -  if (regnum >= AMD64_CS_REGNUM && regnum <= AMD64_GS_REGNUM)
> -    return builtin_type (gdbarch)->builtin_int32;
> -  if (regnum >= AMD64_ST0_REGNUM && regnum <= AMD64_ST0_REGNUM + 7)
> -    return i387_ext_type (gdbarch);
> -  if (regnum >= AMD64_FCTRL_REGNUM && regnum <= AMD64_FCTRL_REGNUM + 7)
> -    return builtin_type (gdbarch)->builtin_int32;
> -  if (regnum >= AMD64_XMM0_REGNUM && regnum <= AMD64_XMM0_REGNUM + 15)
> -    return i386_sse_type (gdbarch);
> -  if (regnum == AMD64_MXCSR_REGNUM)
> -    return i386_mxcsr_type (gdbarch);
> -
> -  internal_error (__FILE__, __LINE__, _("invalid regnum"));
> -}
> -
>  /* DWARF Register Number Mapping as defined in the System V psABI,
>     section 3.6.  */
>  
> @@ -2153,11 +2114,19 @@ void
>  amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
>  {
>    struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> +  const struct target_desc *tdesc = info.target_desc;
>  
>    /* AMD64 generally uses `fxsave' instead of `fsave' for saving its
>       floating-point registers.  */
>    tdep->sizeof_fpregset = I387_SIZEOF_FXSAVE;
>  
> +  if (! tdesc_has_registers (tdesc))
> +    tdesc = tdesc_amd64;
> +  tdep->tdesc = tdesc;
> +
> +  tdep->num_core_regs = AMD64_NUM_GREGS + I387_NUM_REGS;
> +  tdep->register_names = amd64_register_names;
> +
>    /* AMD64 has an FPU and 16 SSE registers.  */
>    tdep->st0_regnum = AMD64_ST0_REGNUM;
>    tdep->num_xmm_regs = 16;
> @@ -2173,8 +2142,6 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
>    set_gdbarch_long_double_bit (gdbarch, 128);
>  
>    set_gdbarch_num_regs (gdbarch, AMD64_NUM_REGS);
> -  set_gdbarch_register_name (gdbarch, amd64_register_name);
> -  set_gdbarch_register_type (gdbarch, amd64_register_type);
>  
>    /* Register numbers of various important registers.  */
>    set_gdbarch_sp_regnum (gdbarch, AMD64_RSP_REGNUM); /* %rsp */
> @@ -2236,6 +2203,15 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
>  
>    set_gdbarch_get_longjmp_target (gdbarch, amd64_get_longjmp_target);
>  }
> +
> +/* Provide a prototype to silence -Wmissing-prototypes.  */
> +void _initialize_amd64_tdep (void);
> +
> +void
> +_initialize_amd64_tdep (void)
> +{
> +  initialize_tdesc_amd64 ();
> +}
>  
>  
>  /* The 64-bit FXSAVE format differs from the 32-bit format in the
> diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
> index 5bf82e2..7fecced 100644
> --- a/gdb/gdbserver/Makefile.in
> +++ b/gdb/gdbserver/Makefile.in
> @@ -203,9 +203,9 @@ clean:
>  	rm -f *.o ${ADD_FILES} *~
>  	rm -f version.c
>  	rm -f gdbserver$(EXEEXT) gdbreplay$(EXEEXT) core make.log
> -	rm -f reg-arm.c reg-i386.c reg-ia64.c reg-m32r.c reg-m68k.c
> -	rm -f reg-sh.c reg-sparc.c reg-spu.c reg-x86-64.c reg-i386-linux.c
> -	rm -f reg-cris.c reg-crisv32.c reg-x86-64-linux.c reg-xtensa.c
> +	rm -f reg-arm.c i386.c reg-ia64.c reg-m32r.c reg-m68k.c
> +	rm -f reg-sh.c reg-sparc.c reg-spu.c amd64.c i386-linux.c
> +	rm -f reg-cris.c reg-crisv32.c amd64-linux.c reg-xtensa.c
>  	rm -f arm-with-iwmmxt.c
>  	rm -f arm-with-vfpv2.c arm-with-vfpv3.c arm-with-neon.c
>  	rm -f mips-linux.c mips64-linux.c
> @@ -345,12 +345,12 @@ reg-cris.c : $(srcdir)/../regformats/reg-cris.dat $(regdat_sh)
>  reg-crisv32.o : reg-crisv32.c $(regdef_h)
>  reg-crisv32.c : $(srcdir)/../regformats/reg-crisv32.dat $(regdat_sh)
>  	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-crisv32.dat reg-crisv32.c
> -reg-i386.o : reg-i386.c $(regdef_h)
> -reg-i386.c : $(srcdir)/../regformats/reg-i386.dat $(regdat_sh)
> -	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-i386.dat reg-i386.c
> -reg-i386-linux.o : reg-i386-linux.c $(regdef_h)
> -reg-i386-linux.c : $(srcdir)/../regformats/reg-i386-linux.dat $(regdat_sh)
> -	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-i386-linux.dat reg-i386-linux.c
> +i386.o : i386.c $(regdef_h)
> +i386.c : $(srcdir)/../regformats/i386/i386.dat $(regdat_sh)
> +	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/i386.dat i386.c
> +i386-linux.o : i386-linux.c $(regdef_h)
> +i386-linux.c : $(srcdir)/../regformats/i386/i386-linux.dat $(regdat_sh)
> +	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/i386-linux.dat i386-linux.c
>  reg-ia64.o : reg-ia64.c $(regdef_h)
>  reg-ia64.c : $(srcdir)/../regformats/reg-ia64.dat $(regdat_sh)
>  	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-ia64.dat reg-ia64.c
> @@ -432,12 +432,12 @@ reg-sparc64.c : $(srcdir)/../regformats/reg-sparc64.dat $(regdat_sh)
>  reg-spu.o : reg-spu.c $(regdef_h)
>  reg-spu.c : $(srcdir)/../regformats/reg-spu.dat $(regdat_sh)
>  	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-spu.dat reg-spu.c
> -reg-x86-64.o : reg-x86-64.c $(regdef_h)
> -reg-x86-64.c : $(srcdir)/../regformats/reg-x86-64.dat $(regdat_sh)
> -	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-x86-64.dat reg-x86-64.c
> -reg-x86-64-linux.o : reg-x86-64-linux.c $(regdef_h)
> -reg-x86-64-linux.c : $(srcdir)/../regformats/reg-x86-64-linux.dat $(regdat_sh)
> -	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-x86-64-linux.dat reg-x86-64-linux.c
> +amd64.o : amd64.c $(regdef_h)
> +amd64.c : $(srcdir)/../regformats/i386/amd64.dat $(regdat_sh)
> +	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/amd64.dat amd64.c
> +amd64-linux.o : amd64-linux.c $(regdef_h)
> +amd64-linux.c : $(srcdir)/../regformats/i386/amd64-linux.dat $(regdat_sh)
> +	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/i386/amd64-linux.dat amd64-linux.c
>  reg-xtensa.o : reg-xtensa.c $(regdef_h)
>  reg-xtensa.c : $(srcdir)/../regformats/reg-xtensa.dat $(regdat_sh)
>  	$(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-xtensa.dat reg-xtensa.c
> diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
> index f6d92b3..e5818cd 100644
> --- a/gdb/gdbserver/configure.srv
> +++ b/gdb/gdbserver/configure.srv
> @@ -22,6 +22,18 @@
>  # Default hostio_last_error implementation
>  srv_hostio_err_objs="hostio-errno.o"
>  
> +srv_i386_regobj=i386.o
> +srv_i386_linux_regobj=i386-linux.o
> +srv_amd64_regobj=amd64.o
> +srv_amd64_linux_regobj=amd64-linux.o
> +
> +srv_i386_32bit_xmlfiles="i386/32bit-core.xml i386/32bit-sse.xml"
> +srv_i386_64bit_xmlfiles="i386/64bit-core.xml i386/64bit-sse.xml"
> +srv_i386_xmlfiles="i386/i386.xml $srv_i386_32bit_xmlfiles"
> +srv_amd64_xmlfiles="i386/amd64.xml $srv_i386_64bit_xmlfiles"
> +srv_i386_linux_xmlfiles="i386/i386-linux.xml i386/32bit-linux.xml $srv_i386_32bit_xmlfiles"
> +srv_amd64_linux_xmlfiles="i386/amd64-linux.xml i386/64bit-linux.xml $srv_i386_64bit_xmlfiles"
> +
>  # Input is taken from the "${target}" variable.
>  
>  case "${target}" in
> @@ -60,12 +72,15 @@ case "${target}" in
>  			srv_linux_usrregs=yes
>  			srv_linux_thread_db=yes
>  			;;
> -  i[34567]86-*-cygwin*)	srv_regobj=reg-i386.o
> +  i[34567]86-*-cygwin*)	srv_regobj="$srv_i386_regobj"
>  			srv_tgtobj="i386-low.o win32-low.o win32-i386-low.o"
> +			srv_xmlfiles="$srv_i386_xmlfiles"
>  			;;
> -  i[34567]86-*-linux*)	srv_regobj=reg-i386-linux.o
> +  i[34567]86-*-linux*)	srv_regobj="$srv_i386_linux_regobj"
> +			srv_xmlfiles="$srv_i386_linux_xmlfiles"
>  			if test "$gdb_cv_i386_is_x86_64" = yes ; then
> -			    srv_regobj="reg-x86-64-linux.o $srv_regobj"
> +			    srv_regobj="$srv_regobj $srv_amd64_linux_regobj"
> +			    srv_xmlfiles="${srv_xmlfiles} $srv_amd64_linux_xmlfiles"
>  			fi
>  			srv_tgtobj="linux-low.o linux-x86-low.o i386-low.o i387-fp.o"
>  			srv_linux_usrregs=yes
> @@ -73,20 +88,23 @@ case "${target}" in
>  			srv_linux_thread_db=yes
>  			;;
>    i[34567]86-*-mingw32ce*)
> -			srv_regobj=reg-i386.o
> +			srv_regobj="$srv_i386_regobj"
>  			srv_tgtobj="i386-low.o win32-low.o win32-i386-low.o"
>  			srv_tgtobj="${srv_tgtobj} wincecompat.o"
> +			srv_xmlfiles="$srv_i386_xmlfiles"
>  			# hostio_last_error implementation is in win32-low.c
>  			srv_hostio_err_objs=""
>  			srv_mingw=yes
>  			srv_mingwce=yes
>  			;;
> -  i[34567]86-*-mingw*)	srv_regobj=reg-i386.o
> +  i[34567]86-*-mingw*)	srv_regobj="$srv_i386_regobj"
>  			srv_tgtobj="i386-low.o win32-low.o win32-i386-low.o"
> +			srv_xmlfiles="$srv_i386_xmlfiles"
>  			srv_mingw=yes
>  			;;
> -  i[34567]86-*-nto*)	srv_regobj=reg-i386.o
> +  i[34567]86-*-nto*)	srv_regobj="$srv_i386_regobj"
>  			srv_tgtobj="nto-low.o nto-x86-low.o"
> +			srv_xmlfiles="$srv_i386_xmlfiles"
>  			srv_qnx="yes"
>  			;;
>    ia64-*-linux*)	srv_regobj=reg-ia64.o
> @@ -206,8 +224,9 @@ case "${target}" in
>    spu*-*-*)		srv_regobj=reg-spu.o
>  			srv_tgtobj="spu-low.o"
>  			;;
> -  x86_64-*-linux*)	srv_regobj="reg-x86-64-linux.o reg-i386-linux.o"
> +  x86_64-*-linux*)	srv_regobj="$srv_amd64_linux_regobj $srv_i386_linux_regobj"
>  			srv_tgtobj="linux-low.o linux-x86-low.o i386-low.o i387-fp.o"
> +			srv_xmlfiles="$srv_i386_linux_xmlfiles $srv_amd64_linux_xmlfiles"
>  			srv_linux_usrregs=yes # This is for i386 progs.
>  			srv_linux_regsets=yes
>  			srv_linux_thread_db=yes
> diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
> index 0062432..496baa2 100644
> --- a/gdb/gdbserver/linux-x86-low.c
> +++ b/gdb/gdbserver/linux-x86-low.c
> @@ -27,10 +27,10 @@
>  
>  #include "gdb_proc_service.h"
>  
> -/* Defined in auto-generated file reg-i386-linux.c.  */
> +/* Defined in auto-generated file i386-linux.c.  */
>  void init_registers_i386_linux (void);
> -/* Defined in auto-generated file reg-x86-64-linux.c.  */
> -void init_registers_x86_64_linux (void);
> +/* Defined in auto-generated file amd64-linux.c.  */
> +void init_registers_amd64_linux (void);
>  
>  #include <sys/reg.h>
>  #include <sys/procfs.h>
> @@ -792,7 +792,7 @@ x86_arch_setup (void)
>      }
>    else if (use_64bit)
>      {
> -      init_registers_x86_64_linux ();
> +      init_registers_amd64_linux ();
>  
>        /* Amd64 doesn't have HAVE_LINUX_USRREGS.  */
>        the_low_target.num_regs = -1;
> diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c
> index ff837f2..31b9086 100644
> --- a/gdb/i386-linux-nat.c
> +++ b/gdb/i386-linux-nat.c
> @@ -853,6 +853,14 @@ i386_linux_child_post_startup_inferior (ptid_t ptid)
>    super_post_startup_inferior (ptid);
>  }
>  
> +/* Get Linux/x86 target description from running target.  */
> +
> +static const struct target_desc *
> +i386_linux_read_description (struct target_ops *ops)
> +{
> +  return tdesc_i386_linux;
> +}
> +
>  void
>  _initialize_i386_linux_nat (void)
>  {
> @@ -881,6 +889,8 @@ _initialize_i386_linux_nat (void)
>    t->to_fetch_registers = i386_linux_fetch_inferior_registers;
>    t->to_store_registers = i386_linux_store_inferior_registers;
>  
> +  t->to_read_description = i386_linux_read_description;
> +
>    /* Register the target.  */
>    linux_nat_add_target (t);
>    linux_nat_set_new_thread (t, i386_linux_new_thread);
> diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
> index 5acd229..b23c109 100644
> --- a/gdb/i386-linux-tdep.c
> +++ b/gdb/i386-linux-tdep.c
> @@ -46,6 +46,8 @@
>  #include "linux-record.h"
>  #include <stdint.h>
>  
> +#include "features/i386/i386-linux.c"
> +
>  /* Supported register note sections.  */
>  static struct core_regset_section i386_linux_regset_sections[] =
>  {
> @@ -55,18 +57,6 @@ static struct core_regset_section i386_linux_regset_sections[] =
>    { NULL, 0 }
>  };
>  
> -/* Return the name of register REG.  */
> -
> -static const char *
> -i386_linux_register_name (struct gdbarch *gdbarch, int reg)
> -{
> -  /* Deal with the extra "orig_eax" pseudo register.  */
> -  if (reg == I386_LINUX_ORIG_EAX_REGNUM)
> -    return "orig_eax";
> -
> -  return i386_register_name (gdbarch, reg);
> -}
> -
>  /* Return non-zero, when the register is in the corresponding register
>     group.  Put the LINUX_ORIG_EAX register in the system group.  */
>  static int
> @@ -570,21 +560,57 @@ static int i386_linux_sc_reg_offset[] =
>    0 * 4				/* %gs */
>  };
>  
> +/* Get Linux/x86 target description from core dump.  */
> +
> +static const struct target_desc *
> +i386_linux_core_read_description (struct gdbarch *gdbarch,
> +				  struct target_ops *target,
> +				  bfd *abfd)
> +{
> +  asection *section = bfd_get_section_by_name (abfd, ".reg2");
> +
> +  if (section == NULL)
> +    return NULL;
> +
> +  /* Linux/i386.  */
> +  return tdesc_i386_linux;
> +}
> +
>  static void
>  i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
>  {
>    struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> +  const struct target_desc *tdesc = info.target_desc;
> +  struct tdesc_arch_data *tdesc_data = (void *) info.tdep_info;
> +  const struct tdesc_feature *feature;
> +  int valid_p;
> +
> +  gdb_assert (tdesc_data);
>  
>    /* GNU/Linux uses ELF.  */
>    i386_elf_init_abi (info, gdbarch);
>  
> -  /* Since we have the extra "orig_eax" register on GNU/Linux, we have
> -     to adjust a few things.  */
> +  /* Reserve a number for orig_eax.  */
> +  set_gdbarch_num_regs (gdbarch, I386_LINUX_NUM_REGS);
> +
> +  if (! tdesc_has_registers (tdesc))
> +    tdesc = tdesc_i386_linux;
> +  tdep->tdesc = tdesc;
> +
> +  feature = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.linux");
> +  if (feature == NULL)
> +    return;
>  
> +  valid_p = tdesc_numbered_register (feature, tdesc_data,
> +				     I386_LINUX_ORIG_EAX_REGNUM,
> +				     "orig_eax");
> +  if (!valid_p)
> +    return;
> +
> +  /* Add the %orig_eax register used for syscall restarting.  */
>    set_gdbarch_write_pc (gdbarch, i386_linux_write_pc);
> -  set_gdbarch_num_regs (gdbarch, I386_LINUX_NUM_REGS);
> -  set_gdbarch_register_name (gdbarch, i386_linux_register_name);
> -  set_gdbarch_register_reggroup_p (gdbarch, i386_linux_register_reggroup_p);
> +
> +  tdep->register_reggroup_p = i386_linux_register_reggroup_p;
>  
>    tdep->gregset_reg_offset = i386_linux_gregset_reg_offset;
>    tdep->gregset_num_regs = ARRAY_SIZE (i386_linux_gregset_reg_offset);
> @@ -783,6 +809,9 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
>    /* Install supported register note sections.  */
>    set_gdbarch_core_regset_sections (gdbarch, i386_linux_regset_sections);
>  
> +  set_gdbarch_core_read_description (gdbarch,
> +				     i386_linux_core_read_description);
> +
>    /* Displaced stepping.  */
>    set_gdbarch_displaced_step_copy_insn (gdbarch,
>                                          simple_displaced_step_copy_insn);
> @@ -808,4 +837,7 @@ _initialize_i386_linux_tdep (void)
>  {
>    gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_LINUX,
>  			  i386_linux_init_abi);
> +
> +  /* Initialize the Linux target description  */
> +  initialize_tdesc_i386_linux ();
>  }
> diff --git a/gdb/i386-linux-tdep.h b/gdb/i386-linux-tdep.h
> index e66021d..11f7295 100644
> --- a/gdb/i386-linux-tdep.h
> +++ b/gdb/i386-linux-tdep.h
> @@ -35,4 +35,7 @@
>  /* Total number of registers for GNU/Linux.  */
>  #define I386_LINUX_NUM_REGS (I386_LINUX_ORIG_EAX_REGNUM + 1)
>  
> +/* Linux target description.  */
> +extern struct target_desc *tdesc_i386_linux;
> +
>  #endif /* i386-linux-tdep.h */
> diff --git a/gdb/i386-nto-tdep.c b/gdb/i386-nto-tdep.c
> index 06fc555..09c55e2 100644
> --- a/gdb/i386-nto-tdep.c
> +++ b/gdb/i386-nto-tdep.c
> @@ -122,7 +122,7 @@ i386nto_regset_id (int regno)
>      return NTO_REG_END;
>    else if (regno < I386_NUM_GREGS)
>      return NTO_REG_GENERAL;
> -  else if (regno < I386_NUM_GREGS + I386_NUM_FREGS)
> +  else if (regno < I386_NUM_GREGS + I387_NUM_REGS)
>      return NTO_REG_FLOAT;
>    else if (regno < I386_SSE_NUM_REGS)
>      return NTO_REG_FLOAT; /* We store xmm registers in fxsave_area.  */
> diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
> index 83aa81f..1c188fd 100644
> --- a/gdb/i386-tdep.c
> +++ b/gdb/i386-tdep.c
> @@ -54,9 +54,11 @@
>  #include "record.h"
>  #include <stdint.h>
>  
> +#include "features/i386/i386.c"
> +
>  /* Register names.  */
>  
> -static char *i386_register_names[] =
> +static const char *i386_register_names[] =
>  {
>    "eax",   "ecx",    "edx",   "ebx",
>    "esp",   "ebp",    "esi",   "edi",
> @@ -71,11 +73,9 @@ static char *i386_register_names[] =
>    "mxcsr"
>  };
>  
> -static const int i386_num_register_names = ARRAY_SIZE (i386_register_names);
> -
>  /* Register names for MMX pseudo-registers.  */
>  
> -static char *i386_mmx_names[] =
> +static const char *i386_mmx_names[] =
>  {
>    "mm0", "mm1", "mm2", "mm3",
>    "mm4", "mm5", "mm6", "mm7"
> @@ -147,16 +147,11 @@ i386_fpc_regnum_p (struct gdbarch *gdbarch, int regnum)
>  
>  /* Return the name of register REGNUM.  */
>  
> -const char *
> -i386_register_name (struct gdbarch *gdbarch, int regnum)
> +static const char *
> +i386_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
>  {
> -  if (i386_mmx_regnum_p (gdbarch, regnum))
> -    return i386_mmx_names[regnum - I387_MM0_REGNUM (gdbarch_tdep (gdbarch))];
> -
> -  if (regnum >= 0 && regnum < i386_num_register_names)
> -    return i386_register_names[regnum];
> -
> -  return NULL;
> +  gdb_assert (i386_mmx_regnum_p (gdbarch, regnum));
> +  return i386_mmx_names[regnum - I387_MM0_REGNUM (gdbarch_tdep (gdbarch))];
>  }
>  
>  /* Convert a dbx register number REG to the appropriate register
> @@ -2112,87 +2107,22 @@ i386_return_value (struct gdbarch *gdbarch, struct type *func_type,
>  }
>  
>  
> -/* Construct types for ISA-specific registers.  */
> -struct type *
> -i386_eflags_type (struct gdbarch *gdbarch)
> -{
> -  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> -
> -  if (!tdep->i386_eflags_type)
> -    {
> -      struct type *type;
> -
> -      type = arch_flags_type (gdbarch, "builtin_type_i386_eflags", 4);
> -      append_flags_type_flag (type, 0, "CF");
> -      append_flags_type_flag (type, 1, NULL);
> -      append_flags_type_flag (type, 2, "PF");
> -      append_flags_type_flag (type, 4, "AF");
> -      append_flags_type_flag (type, 6, "ZF");
> -      append_flags_type_flag (type, 7, "SF");
> -      append_flags_type_flag (type, 8, "TF");
> -      append_flags_type_flag (type, 9, "IF");
> -      append_flags_type_flag (type, 10, "DF");
> -      append_flags_type_flag (type, 11, "OF");
> -      append_flags_type_flag (type, 14, "NT");
> -      append_flags_type_flag (type, 16, "RF");
> -      append_flags_type_flag (type, 17, "VM");
> -      append_flags_type_flag (type, 18, "AC");
> -      append_flags_type_flag (type, 19, "VIF");
> -      append_flags_type_flag (type, 20, "VIP");
> -      append_flags_type_flag (type, 21, "ID");
> -
> -      tdep->i386_eflags_type = type;
> -    }
> -
> -  return tdep->i386_eflags_type;
> -}
> -
> -struct type *
> -i386_mxcsr_type (struct gdbarch *gdbarch)
> -{
> -  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> -
> -  if (!tdep->i386_mxcsr_type)
> -    {
> -      struct type *type;
> -
> -      type = arch_flags_type (gdbarch, "builtin_type_i386_mxcsr", 4);
> -      append_flags_type_flag (type, 0, "IE");
> -      append_flags_type_flag (type, 1, "DE");
> -      append_flags_type_flag (type, 2, "ZE");
> -      append_flags_type_flag (type, 3, "OE");
> -      append_flags_type_flag (type, 4, "UE");
> -      append_flags_type_flag (type, 5, "PE");
> -      append_flags_type_flag (type, 6, "DAZ");
> -      append_flags_type_flag (type, 7, "IM");
> -      append_flags_type_flag (type, 8, "DM");
> -      append_flags_type_flag (type, 9, "ZM");
> -      append_flags_type_flag (type, 10, "OM");
> -      append_flags_type_flag (type, 11, "UM");
> -      append_flags_type_flag (type, 12, "PM");
> -      append_flags_type_flag (type, 15, "FZ");
> -
> -      tdep->i386_mxcsr_type = type;
> -    }
> -
> -  return tdep->i386_mxcsr_type;
> -}
> -
>  struct type *
>  i387_ext_type (struct gdbarch *gdbarch)
>  {
>    struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
>  
>    if (!tdep->i387_ext_type)
> -    tdep->i387_ext_type
> -      = arch_float_type (gdbarch, -1, "builtin_type_i387_ext",
> -			 floatformats_i387_ext);
> +    {
> +      tdep->i387_ext_type = tdesc_find_type (gdbarch, "i387_ext");
> +      gdb_assert (tdep->i387_ext_type != NULL);
> +    }
>  
>    return tdep->i387_ext_type;
>  }
>  
>  /* Construct vector type for MMX registers.  */
> -struct type *
> +static struct type *
>  i386_mmx_type (struct gdbarch *gdbarch)
>  {
>    struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> @@ -2233,84 +2163,14 @@ i386_mmx_type (struct gdbarch *gdbarch)
>    return tdep->i386_mmx_type;
>  }
>  
> -struct type *
> -i386_sse_type (struct gdbarch *gdbarch)
> -{
> -  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
> -
> -  if (!tdep->i386_sse_type)
> -    {
> -      const struct builtin_type *bt = builtin_type (gdbarch);
> -
> -      /* The type we're building is this: */
> -#if 0
> -      union __gdb_builtin_type_vec128i
> -      {
> -        int128_t uint128;
> -        int64_t v2_int64[2];
> -        int32_t v4_int32[4];
> -        int16_t v8_int16[8];
> -        int8_t v16_int8[16];
> -        double v2_double[2];
> -        float v4_float[4];
> -      };
> -#endif
> -
> -      struct type *t;
> -
> -      t = arch_composite_type (gdbarch,
> -			       "__gdb_builtin_type_vec128i", TYPE_CODE_UNION);
> -      append_composite_type_field (t, "v4_float",
> -				   init_vector_type (bt->builtin_float, 4));
> -      append_composite_type_field (t, "v2_double",
> -				   init_vector_type (bt->builtin_double, 2));
> -      append_composite_type_field (t, "v16_int8",
> -				   init_vector_type (bt->builtin_int8, 16));
> -      append_composite_type_field (t, "v8_int16",
> -				   init_vector_type (bt->builtin_int16, 8));
> -      append_composite_type_field (t, "v4_int32",
> -				   init_vector_type (bt->builtin_int32, 4));
> -      append_composite_type_field (t, "v2_int64",
> -				   init_vector_type (bt->builtin_int64, 2));
> -      append_composite_type_field (t, "uint128", bt->builtin_int128);
> -
> -      TYPE_VECTOR (t) = 1;
> -      TYPE_NAME (t) = "builtin_type_vec128i";
> -      tdep->i386_sse_type = t;
> -    }
> -
> -  return tdep->i386_sse_type;
> -}
> -
>  /* Return the GDB type object for the "standard" data type of data in
> -   register REGNUM.  Perhaps %esi and %edi should go here, but
> -   potentially they could be used for things other than address.  */
> +   register REGNUM. */
>  
>  static struct type *
> -i386_register_type (struct gdbarch *gdbarch, int regnum)
> +i386_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
>  {
> -  if (regnum == I386_EIP_REGNUM)
> -    return builtin_type (gdbarch)->builtin_func_ptr;
> -
> -  if (regnum == I386_EFLAGS_REGNUM)
> -    return i386_eflags_type (gdbarch);
> -
> -  if (regnum == I386_EBP_REGNUM || regnum == I386_ESP_REGNUM)
> -    return builtin_type (gdbarch)->builtin_data_ptr;
> -
> -  if (i386_fp_regnum_p (gdbarch, regnum))
> -    return i387_ext_type (gdbarch);
> -
> -  if (i386_mmx_regnum_p (gdbarch, regnum))
> -    return i386_mmx_type (gdbarch);
> -
> -  if (i386_sse_regnum_p (gdbarch, regnum))
> -    return i386_sse_type (gdbarch);
> -
> -  if (regnum == I387_MXCSR_REGNUM (gdbarch_tdep (gdbarch)))
> -    return i386_mxcsr_type (gdbarch);
> -
> -  return builtin_type (gdbarch)->builtin_int;
> +  gdb_assert (i386_mmx_regnum_p (gdbarch, regnum));
> +  return i386_mmx_type (gdbarch);
>  }
>  
>  /* Map a cooked register onto a raw register or memory.  For the i386,
> @@ -2761,7 +2621,7 @@ i386_go32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
>  
>    /* DJGPP does not support the SSE registers.  */
>    tdep->num_xmm_regs = 0;
> -  set_gdbarch_num_regs (gdbarch, I386_NUM_GREGS + I386_NUM_FREGS);
> +  set_gdbarch_num_regs (gdbarch, I386_NUM_GREGS + I387_NUM_REGS);
>  
>    /* Native compiler is GCC, which uses the SVR4 register numbering
>       even in COFF and STABS.  See the comment in i386_gdbarch_init,
> @@ -5623,12 +5483,50 @@ i386_fast_tracepoint_valid_at (struct gdbarch *gdbarch,
>    return 1;
>  }
>  
> +static int
> +i386_validate_tdesc_p (struct gdbarch_tdep *tdep,
> +		       struct tdesc_arch_data *tdesc_data)
> +{
> +  const struct target_desc *tdesc = tdep->tdesc;
> +  const struct tdesc_feature *feature_core, *feature_vector;
> +  int i, num_regs, valid_p;
> +
> +  if (! tdesc_has_registers (tdesc))
> +    return 0;
> +
> +  /* Get core registers.  */
> +  feature_core = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.core");
> +
> +  /* Get SSE registers.  */
> +  feature_vector = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.sse");
> +
> +  if (feature_core == NULL || feature_vector == NULL)
> +    return 0;
> +
> +  valid_p = 1;
> +
> +  num_regs = tdep->num_core_regs;
> +  for (i = 0; i < num_regs; i++)
> +    valid_p &= tdesc_numbered_register (feature_core, tdesc_data, i,
> +					tdep->register_names[i]);
> +
> +  /* Need to include %mxcsr, so add one.  */
> +  num_regs += tdep->num_xmm_regs + 1;
> +  for (; i < num_regs; i++)
> +    valid_p &= tdesc_numbered_register (feature_vector, tdesc_data, i,
> +					tdep->register_names[i]);
> +
> +  return valid_p;
> +}
> +
>  
>  static struct gdbarch *
>  i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  {
>    struct gdbarch_tdep *tdep;
>    struct gdbarch *gdbarch;
> +  struct tdesc_arch_data *tdesc_data;
> +  const struct target_desc *tdesc;
>  
>    /* If there is already a candidate, use it.  */
>    arches = gdbarch_list_lookup_by_info (arches, &info);
> @@ -5696,12 +5594,6 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>       alignment.  */
>    set_gdbarch_long_double_bit (gdbarch, 96);
>  
> -  /* The default ABI includes general-purpose registers, 
> -     floating-point registers, and the SSE registers.  */
> -  set_gdbarch_num_regs (gdbarch, I386_SSE_NUM_REGS);
> -  set_gdbarch_register_name (gdbarch, i386_register_name);
> -  set_gdbarch_register_type (gdbarch, i386_register_type);
> -
>    /* Register numbers of various important registers.  */
>    set_gdbarch_sp_regnum (gdbarch, I386_ESP_REGNUM); /* %esp */
>    set_gdbarch_pc_regnum (gdbarch, I386_EIP_REGNUM); /* %eip */
> @@ -5772,11 +5664,6 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  
>    set_gdbarch_frame_args_skip (gdbarch, 8);
>  
> -  /* Wire in the MMX registers.  */
> -  set_gdbarch_num_pseudo_regs (gdbarch, i386_num_mmx_regs);
> -  set_gdbarch_pseudo_register_read (gdbarch, i386_pseudo_register_read);
> -  set_gdbarch_pseudo_register_write (gdbarch, i386_pseudo_register_write);
> -
>    set_gdbarch_print_insn (gdbarch, i386_print_insn);
>  
>    set_gdbarch_dummy_id (gdbarch, i386_dummy_id);
> @@ -5785,7 +5672,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  
>    /* Add the i386 register groups.  */
>    i386_add_reggroups (gdbarch);
> -  set_gdbarch_register_reggroup_p (gdbarch, i386_register_reggroup_p);
> +  tdep->register_reggroup_p = i386_register_reggroup_p;
>  
>    /* Helper for function argument information.  */
>    set_gdbarch_fetch_pointer_argument (gdbarch, i386_fetch_pointer_argument);
> @@ -5803,9 +5690,49 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
>  
>    frame_base_set_default (gdbarch, &i386_frame_base);
>  
> +  /* Wire in the MMX registers.  */
> +  set_gdbarch_num_pseudo_regs (gdbarch, i386_num_mmx_regs);
> +  set_gdbarch_pseudo_register_read (gdbarch, i386_pseudo_register_read);
> +  set_gdbarch_pseudo_register_write (gdbarch, i386_pseudo_register_write);
> +
> +  set_tdesc_pseudo_register_type (gdbarch, i386_pseudo_register_type);
> +  set_tdesc_pseudo_register_name (gdbarch, i386_pseudo_register_name);
> +
> +  /* The default ABI includes general-purpose registers, 
> +     floating-point registers, and the SSE registers.  */
> +  set_gdbarch_num_regs (gdbarch, I386_SSE_NUM_REGS);
> +
> +  /* Get the x86 target description from INFO.  */
> +  tdesc = info.target_desc;
> +  if (! tdesc_has_registers (tdesc))
> +    tdesc = tdesc_i386;
> +  tdep->tdesc = tdesc;
> +
> +  tdep->num_core_regs = I386_NUM_GREGS + I387_NUM_REGS;
> +  tdep->register_names = i386_register_names;
> +
> +  tdesc_data = tdesc_data_alloc ();
> +
>    /* Hook in ABI-specific overrides, if they have been registered.  */
> +  info.tdep_info = (void *) tdesc_data;
>    gdbarch_init_osabi (info, gdbarch);
>  
> +  /* Target description may be changed.  */
> +  tdesc = tdep->tdesc;
> +
> +  if (!i386_validate_tdesc_p (tdep, tdesc_data))
> +    {
> +      tdesc_data_cleanup (tdesc_data);
> +      xfree (tdep);
> +      gdbarch_free (gdbarch);
> +      return NULL;
> +    }
> +
> +  tdesc_use_registers (gdbarch, tdesc, tdesc_data);
> +
> +  /* Override gdbarch_register_reggroup_p set in tdesc_use_registers.  */
> +  set_gdbarch_register_reggroup_p (gdbarch, tdep->register_reggroup_p);
> +
>    /* Hook in the legacy prologue-based unwinders last (fallback).  */
>    frame_unwind_append_unwinder (gdbarch, &i386_sigtramp_frame_unwind);
>    frame_unwind_append_unwinder (gdbarch, &i386_frame_unwind);
> @@ -5882,4 +5809,7 @@ is \"default\"."),
>  
>    /* Initialize the i386-specific register groups.  */
>    i386_init_reggroups ();
> +
> +  /* Initialize the standard target descriptions.  */
> +  initialize_tdesc_i386 ();
>  }
> diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h
> index 5915eb9..a64e5c3 100644
> --- a/gdb/i386-tdep.h
> +++ b/gdb/i386-tdep.h
> @@ -118,9 +118,21 @@ struct gdbarch_tdep
>       of MMX support.  */
>    int mm0_regnum;
>  
> +  /* Number of core registers.  */
> +  int num_core_regs;
> +
>    /* Number of SSE registers.  */
>    int num_xmm_regs;
>  
> +  /* Register names.  */
> +  const char **register_names;
> +
> +  /* Target description.  */
> +  const struct target_desc *tdesc;
> +
> +  /* Register group function.  */
> +  const void *register_reggroup_p;
> +
>    /* Offset of saved PC in jmp_buf.  */
>    int jb_pc_offset;
>  
> @@ -147,10 +159,7 @@ struct gdbarch_tdep
>    int sc_sp_offset;
>  
>    /* ISA-specific data types.  */
> -  struct type *i386_eflags_type;
> -  struct type *i386_mxcsr_type;
>    struct type *i386_mmx_type;
> -  struct type *i386_sse_type;
>    struct type *i387_ext_type;
>  
>    /* Process record/replay target.  */
> @@ -196,7 +205,8 @@ enum i386_regnum
>    I386_ES_REGNUM,		/* %es */
>    I386_FS_REGNUM,		/* %fs */
>    I386_GS_REGNUM,		/* %gs */
> -  I386_ST0_REGNUM		/* %st(0) */
> +  I386_ST0_REGNUM,		/* %st(0) */
> +  I386_MXCSR_REGNUM = 40	/* %mxcsr */ 
>  };
>  
>  /* Register numbers of RECORD_REGMAP.  */
> @@ -230,20 +240,14 @@ enum record_i386_regnum
>  };
>  
>  #define I386_NUM_GREGS	16
> -#define I386_NUM_FREGS	16
>  #define I386_NUM_XREGS  9
>  
> -#define I386_SSE_NUM_REGS	(I386_NUM_GREGS + I386_NUM_FREGS \
> -				 + I386_NUM_XREGS)
> +#define I386_SSE_NUM_REGS	(I386_MXCSR_REGNUM + 1)
>  
>  /* Size of the largest register.  */
>  #define I386_MAX_REGISTER_SIZE	16
>  
>  /* Types for i386-specific registers.  */
> -extern struct type *i386_eflags_type (struct gdbarch *gdbarch);
> -extern struct type *i386_mxcsr_type (struct gdbarch *gdbarch);
> -extern struct type *i386_mmx_type (struct gdbarch *gdbarch);
> -extern struct type *i386_sse_type (struct gdbarch *gdbarch);
>  extern struct type *i387_ext_type (struct gdbarch *gdbarch);
>  
>  /* Segment selectors.  */
> @@ -263,9 +267,6 @@ extern CORE_ADDR i386_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
>  /* Return whether the THIS_FRAME corresponds to a sigtramp routine.  */
>  extern int i386_sigtramp_p (struct frame_info *this_frame);
>  
> -/* Return the name of register REGNUM.  */
> -extern char const *i386_register_name (struct gdbarch * gdbarch, int regnum);
> -
>  /* Return non-zero if REGNUM is a member of the specified group.  */
>  extern int i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
>  				     struct reggroup *group);
> diff --git a/gdb/i387-tdep.h b/gdb/i387-tdep.h
> index 5a08ace..645eb91 100644
> --- a/gdb/i387-tdep.h
> +++ b/gdb/i387-tdep.h
> @@ -27,6 +27,9 @@ struct regcache;
>  struct type;
>  struct ui_file;
>  
> +/* Number of i387 floating point registers.  */
> +#define I387_NUM_REGS	16
> +
>  #define I387_ST0_REGNUM(tdep) ((tdep)->st0_regnum)
>  #define I387_NUM_XMM_REGS(tdep) ((tdep)->num_xmm_regs)
>  #define I387_MM0_REGNUM(tdep) ((tdep)->mm0_regnum)
> diff --git a/gdb/regformats/i386/amd64-linux.dat b/gdb/regformats/i386/amd64-linux.dat
> new file mode 100644
> index 0000000..02a2c78
> --- /dev/null
> +++ b/gdb/regformats/i386/amd64-linux.dat
> @@ -0,0 +1,62 @@
> +# DO NOT EDIT: generated from i386/amd64-linux.xml
> +name:amd64_linux
> +xmltarget:amd64-linux.xml
> +expedite:rbp,rsp,rip
> +64:rax
> +64:rbx
> +64:rcx
> +64:rdx
> +64:rsi
> +64:rdi
> +64:rbp
> +64:rsp
> +64:r8
> +64:r9
> +64:r10
> +64:r11
> +64:r12
> +64:r13
> +64:r14
> +64:r15
> +64:rip
> +32:eflags
> +32:cs
> +32:ss
> +32:ds
> +32:es
> +32:fs
> +32:gs
> +80:st0
> +80:st1
> +80:st2
> +80:st3
> +80:st4
> +80:st5
> +80:st6
> +80:st7
> +32:fctrl
> +32:fstat
> +32:ftag
> +32:fiseg
> +32:fioff
> +32:foseg
> +32:fooff
> +32:fop
> +128:xmm0
> +128:xmm1
> +128:xmm2
> +128:xmm3
> +128:xmm4
> +128:xmm5
> +128:xmm6
> +128:xmm7
> +128:xmm8
> +128:xmm9
> +128:xmm10
> +128:xmm11
> +128:xmm12
> +128:xmm13
> +128:xmm14
> +128:xmm15
> +32:mxcsr
> +64:orig_rax
> diff --git a/gdb/regformats/i386/amd64.dat b/gdb/regformats/i386/amd64.dat
> new file mode 100644
> index 0000000..d589218
> --- /dev/null
> +++ b/gdb/regformats/i386/amd64.dat
> @@ -0,0 +1,61 @@
> +# DO NOT EDIT: generated from i386/amd64.xml
> +name:amd64
> +xmltarget:amd64.xml
> +expedite:rbp,rsp,rip
> +64:rax
> +64:rbx
> +64:rcx
> +64:rdx
> +64:rsi
> +64:rdi
> +64:rbp
> +64:rsp
> +64:r8
> +64:r9
> +64:r10
> +64:r11
> +64:r12
> +64:r13
> +64:r14
> +64:r15
> +64:rip
> +32:eflags
> +32:cs
> +32:ss
> +32:ds
> +32:es
> +32:fs
> +32:gs
> +80:st0
> +80:st1
> +80:st2
> +80:st3
> +80:st4
> +80:st5
> +80:st6
> +80:st7
> +32:fctrl
> +32:fstat
> +32:ftag
> +32:fiseg
> +32:fioff
> +32:foseg
> +32:fooff
> +32:fop
> +128:xmm0
> +128:xmm1
> +128:xmm2
> +128:xmm3
> +128:xmm4
> +128:xmm5
> +128:xmm6
> +128:xmm7
> +128:xmm8
> +128:xmm9
> +128:xmm10
> +128:xmm11
> +128:xmm12
> +128:xmm13
> +128:xmm14
> +128:xmm15
> +32:mxcsr
> diff --git a/gdb/regformats/i386/i386-linux.dat b/gdb/regformats/i386/i386-linux.dat
> new file mode 100644
> index 0000000..6fef8d9
> --- /dev/null
> +++ b/gdb/regformats/i386/i386-linux.dat
> @@ -0,0 +1,46 @@
> +# DO NOT EDIT: generated from i386/i386-linux.xml
> +name:i386_linux
> +xmltarget:i386-linux.xml
> +expedite:ebp,esp,eip
> +32:eax
> +32:ecx
> +32:edx
> +32:ebx
> +32:esp
> +32:ebp
> +32:esi
> +32:edi
> +32:eip
> +32:eflags
> +32:cs
> +32:ss
> +32:ds
> +32:es
> +32:fs
> +32:gs
> +80:st0
> +80:st1
> +80:st2
> +80:st3
> +80:st4
> +80:st5
> +80:st6
> +80:st7
> +32:fctrl
> +32:fstat
> +32:ftag
> +32:fiseg
> +32:fioff
> +32:foseg
> +32:fooff
> +32:fop
> +128:xmm0
> +128:xmm1
> +128:xmm2
> +128:xmm3
> +128:xmm4
> +128:xmm5
> +128:xmm6
> +128:xmm7
> +32:mxcsr
> +32:orig_eax
> diff --git a/gdb/regformats/i386/i386.dat b/gdb/regformats/i386/i386.dat
> new file mode 100644
> index 0000000..923d879
> --- /dev/null
> +++ b/gdb/regformats/i386/i386.dat
> @@ -0,0 +1,45 @@
> +# DO NOT EDIT: generated from i386/i386.xml
> +name:i386
> +xmltarget:i386.xml
> +expedite:ebp,esp,eip
> +32:eax
> +32:ecx
> +32:edx
> +32:ebx
> +32:esp
> +32:ebp
> +32:esi
> +32:edi
> +32:eip
> +32:eflags
> +32:cs
> +32:ss
> +32:ds
> +32:es
> +32:fs
> +32:gs
> +80:st0
> +80:st1
> +80:st2
> +80:st3
> +80:st4
> +80:st5
> +80:st6
> +80:st7
> +32:fctrl
> +32:fstat
> +32:ftag
> +32:fiseg
> +32:fioff
> +32:foseg
> +32:fooff
> +32:fop
> +128:xmm0
> +128:xmm1
> +128:xmm2
> +128:xmm3
> +128:xmm4
> +128:xmm5
> +128:xmm6
> +128:xmm7
> +32:mxcsr
> diff --git a/gdb/testsuite/gdb.xml/tdesc-regs.exp b/gdb/testsuite/gdb.xml/tdesc-regs.exp
> index 0922ca3..8eae0bd 100644
> --- a/gdb/testsuite/gdb.xml/tdesc-regs.exp
> +++ b/gdb/testsuite/gdb.xml/tdesc-regs.exp
> @@ -25,6 +25,7 @@ gdb_start
>  
>  set core-regs ""
>  set regdir ""
> +set architecture ""
>  switch -glob -- [istarget] {
>      "*arm-*-*" {
>          set core-regs {arm-core.xml}
> @@ -55,6 +56,16 @@ switch -glob -- [istarget] {
>  	unsupported "register tests"
>  	return 0
>      }
> +    "i?86-*-*" {
> +	set architecture "i386"
> +	set regdir "i386/"
> +        set core-regs {32bit-core.xml 32bit-sse.xml}
> +    }
> +    "x86_64-*-*" {
> +	set architecture "i386:x86-64"
> +	set regdir "i386/"
> +        set core-regs {64bit-core.xml 64bit-sse.xml}
> +    }
>  }
>  
>  # If no core registers were specified, assume this target does not
> @@ -89,12 +100,16 @@ proc load_description { file errmsg } {
>      global subdir
>      global gdb_prompt
>      global core-regs
> +    global architecture
>  
>      file delete "$subdir/regs.xml"
>      set ifd [open "$srcdir/$subdir/$file" r]
>      set ofd [open "$subdir/regs.xml" w]
>      while {[gets $ifd line] >= 0} {
>  	if {[regexp {<xi:include href="core-regs.xml"/>} $line]} {
> +	    if {! [string equal ${architecture} ""]} {
> +		puts $ofd "  <architecture>${architecture}</architecture>"
> +	    }
>  	    foreach src ${core-regs} {
>  		puts $ofd "  <xi:include href=\"$src\"/>"
>  	    }
> 


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