* PATCH: Enable x86 XML target descriptions @ 2010-02-10 20:03 H.J. Lu 2010-02-17 14:59 ` H.J. Lu 2010-02-18 5:44 ` H.J. Lu 0 siblings, 2 replies; 39+ messages in thread From: H.J. Lu @ 2010-02-10 20:03 UTC (permalink / raw) To: GDB 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? BTW, I have a followup patch to support al, ax and eax pseudo registers. Thanks. H.J. ---- gdb/ 2010-02-10 H.J. Lu <hongjiu.lu@intel.com> * amd64-linux-nat.c (_initialize_amd64_linux_nat): Set to_read_description to i386_linux_read_description. * i386-linux-nat.c (_initialize_i386_linux_nat): Likewise. * amd64-linux-tdep.c (amd64_linux_register_name): Removed. (amd64_linux_register_type): Likewise. (amd64_linux_init_abi): Don't call set_gdbarch_num_regs, set_gdbarch_register_name nor set_gdbarch_register_type. Call i386_linux_init_orig_eax and set_gdbarch_core_read_description. * amd64-linux-tdep.h: Include "i386-linux-tdep.h". * amd64-tdep.c (amd64_register_names): Make it global. (amd64_register_name): Removed. (amd64_register_type): Likewise. (amd64_init_abi): Don't call set_gdbarch_num_regs, set_gdbarch_register_name nor set_gdbarch_register_type. * amd64-tdep.h (amd64_register_names): New. * i386-linux-tdep.c: Include "amd64-tdep.h" and * "amd64-linux-tdep.h" instead "i386-tdep.h" and "i386-linux-tdep.h". Include features/i386/i386-linux.c and features/i386/amd64-linux.c. (i386_linux_register_name): Support BFD64. (i386_linux_register_type): New. (i386_linux_init_orig_eax): Likewise. (i386_linux_core_read_description): Likewise. (i386_linux_read_description): Likewise. (i386_linux_init_abi): Don't call set_gdbarch_num_regs nor set_gdbarch_register_name. Call i386_linux_init_orig_eax and set_gdbarch_core_read_description. (_initialize_i386_linux_tdep): Call initialize_tdesc_i386_linux and initialize_tdesc_x86_64_linux. * i386-linux-tdep.h (i386_linux_core_read_description): New. (i386_linux_read_description): Likewise. (i386_linux_init_orig_eax): Likewise. * i386-tdep.c: Include "amd64-tdep.h" instead of "i386-tdep.h". Include features/i386/i386.c and features/i386/amd64.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): Support both 32bit and 64bit x86 target descriptions. Don't call set_gdbarch_register_name nor set_gdbarch_register_type. Call set_tdesc_pseudo_register_type, set_tdesc_pseudo_register_name and tdesc_use_registers. (_initialize_i386_tdep): Call initialize_tdesc_i386 and initialize_tdesc_x86_64. * i386-tdep.h (gdbarch_tdep): Remove i386_eflags_type, i386_mxcsr_type and i386_sse_type. (i386_eflags_type): Removed. (i386_mxcsr_type): Likewise. (i386_mmx_type): Likewise. (i386_sse_type): Likewise. (i386_register_name): Likewise. * 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-10 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. diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c index 5c9e558..2461f74 100644 --- a/gdb/amd64-linux-nat.c +++ b/gdb/amd64-linux-nat.c @@ -712,6 +712,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 = i386_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 01cc1ce..1b53de5 100644 --- a/gdb/amd64-linux-tdep.c +++ b/gdb/amd64-linux-tdep.c @@ -234,26 +234,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) @@ -1282,9 +1262,10 @@ 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); + + /* Support remote stub without XML target description. */ + i386_linux_init_orig_eax (info, gdbarch); + set_gdbarch_register_reggroup_p (gdbarch, amd64_linux_register_reggroup_p); /* Functions for 'catch syscall'. */ @@ -1299,6 +1280,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, + i386_linux_core_read_description); + /* Displaced stepping. */ set_gdbarch_displaced_step_copy_insn (gdbarch, amd64_displaced_step_copy_insn); diff --git a/gdb/amd64-linux-tdep.h b/gdb/amd64-linux-tdep.h index 20a15ca..2f120c6 100644 --- a/gdb/amd64-linux-tdep.h +++ b/gdb/amd64-linux-tdep.h @@ -20,6 +20,8 @@ #ifndef AMD64_LINUX_TDEP_H #define AMD64_LINUX_TDEP_H +#include "i386-linux-tdep.h" + /* Like for i386 GNU/Linux, there is an extra "register" used to control syscall restarting. */ diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index 2b15141..fc5e3e5 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -51,7 +51,7 @@ /* Register information. */ -static const char *amd64_register_names[] = +const char *amd64_register_names[] = { "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "rbp", "rsp", @@ -83,47 +83,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. */ @@ -2172,10 +2131,6 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) floating-point format which has only 80 significant bits. */ 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 */ set_gdbarch_pc_regnum (gdbarch, AMD64_RIP_REGNUM); /* %rip */ diff --git a/gdb/amd64-tdep.h b/gdb/amd64-tdep.h index 363479c..95cf63c 100644 --- a/gdb/amd64-tdep.h +++ b/gdb/amd64-tdep.h @@ -101,6 +101,7 @@ extern void amd64_collect_fxsave (const struct regcache *regcache, int regnum, void amd64_classify (struct type *type, enum amd64_reg_class class[2]); +extern const char *amd64_register_names[]; \f /* Variables exported from amd64nbsd-tdep.c. */ 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..b9aa411 100644 --- a/gdb/i386-linux-nat.c +++ b/gdb/i386-linux-nat.c @@ -881,6 +881,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..847992f 100644 --- a/gdb/i386-linux-tdep.c +++ b/gdb/i386-linux-tdep.c @@ -29,8 +29,8 @@ #include "dwarf2-frame.h" #include "gdb_string.h" -#include "i386-tdep.h" -#include "i386-linux-tdep.h" +#include "amd64-tdep.h" +#include "amd64-linux-tdep.h" #include "linux-tdep.h" #include "glibc-tdep.h" #include "solib-svr4.h" @@ -46,6 +46,11 @@ #include "linux-record.h" #include <stdint.h> +#include "features/i386/i386-linux.c" +#ifdef BFD64 +#include "features/i386/amd64-linux.c" +#endif + /* Supported register note sections. */ static struct core_regset_section i386_linux_regset_sections[] = { @@ -60,11 +65,67 @@ static struct core_regset_section i386_linux_regset_sections[] = 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"; +#ifdef BFD64 + if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 64) + { + if (reg == AMD64_LINUX_ORIG_RAX_REGNUM) + return "orig_rax"; + } + else +#endif + if (reg == I386_LINUX_ORIG_EAX_REGNUM) + return "orig_eax"; + + return tdesc_register_name (gdbarch, reg); +} + +/* Return the type of a register number. */ + +static struct type * +i386_linux_register_type (struct gdbarch *gdbarch, int reg) +{ +#ifdef BFD64 + if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 64) + { + if (reg == AMD64_LINUX_ORIG_RAX_REGNUM) + return builtin_type (gdbarch)->builtin_int64; + } + else +#endif + if (reg == I386_LINUX_ORIG_EAX_REGNUM) + return builtin_type (gdbarch)->builtin_int; + + return tdesc_register_type (gdbarch, reg); +} + +/* Provide orig_eax/orig_rax support if XML target description isn't + available. */ + +void +i386_linux_init_orig_eax (struct gdbarch_info info, + struct gdbarch *gdbarch) +{ + int num_regs; + + /* Return if XML target description is available. */ + if (info.target_desc + && tdesc_find_feature (info.target_desc, + "org.gnu.gdb.i386.linux")) + return; + +#ifdef BFD64 + if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 64) + num_regs = AMD64_LINUX_NUM_REGS; + else +#endif + num_regs = I386_LINUX_NUM_REGS; - return i386_register_name (gdbarch, reg); + /* Support orig_eax/orig_rax. */ + set_gdbarch_num_regs (gdbarch, num_regs); + set_gdbarch_register_name (gdbarch, i386_linux_register_name); + set_gdbarch_register_type (gdbarch, i386_linux_register_type); + set_gdbarch_remote_register_number (gdbarch, + default_remote_register_number); } /* Return non-zero, when the register is in the corresponding register @@ -570,6 +631,46 @@ static int i386_linux_sc_reg_offset[] = 0 * 4 /* %gs */ }; +/* Get Linux/x86 target description from core dump. */ + +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; + + switch (bfd_section_size (abfd, section)) + { +#ifdef BFD64 + case 0x200: + /* Linux/x86-64. */ + return tdesc_amd64_linux; +#endif + case 0x6c: + /* Linux/i386. */ + return tdesc_i386_linux; + default: + return NULL; + } +} + +/* Get Linux/x86 target description from running target. */ + +const struct target_desc * +i386_linux_read_description (struct target_ops *ops) +{ +#ifdef BFD64 + if (gdbarch_ptr_bit (target_gdbarch) == 64) + return tdesc_amd64_linux; + else +#endif + return tdesc_i386_linux; +} + static void i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { @@ -582,8 +683,10 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) to adjust a few things. */ 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); + + /* Support remote stub without XML target description. */ + i386_linux_init_orig_eax (info, gdbarch); + set_gdbarch_register_reggroup_p (gdbarch, i386_linux_register_reggroup_p); tdep->gregset_reg_offset = i386_linux_gregset_reg_offset; @@ -783,6 +886,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 +914,10 @@ _initialize_i386_linux_tdep (void) { gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_LINUX, i386_linux_init_abi); + + /* Initialize the Linux target descriptions */ + initialize_tdesc_i386_linux (); +#ifdef BFD64 + initialize_tdesc_amd64_linux (); +#endif } diff --git a/gdb/i386-linux-tdep.h b/gdb/i386-linux-tdep.h index e66021d..d7330ba 100644 --- a/gdb/i386-linux-tdep.h +++ b/gdb/i386-linux-tdep.h @@ -35,4 +35,16 @@ /* Total number of registers for GNU/Linux. */ #define I386_LINUX_NUM_REGS (I386_LINUX_ORIG_EAX_REGNUM + 1) +/* Get Linux/x86 target description from core dump. */ +extern const struct target_desc *i386_linux_core_read_description + (struct gdbarch *gdbarch, struct target_ops *target, bfd *abfd); + +/* Get Linux/x86 target description from running target. */ +extern const struct target_desc *i386_linux_read_description + (struct target_ops *ops); + +/* Support remote stub without XML target description. */ +extern void i386_linux_init_orig_eax (struct gdbarch_info info, + struct gdbarch *gdbarch); + #endif /* i386-linux-tdep.h */ diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 83aa81f..644e822 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -48,15 +48,20 @@ #include "gdb_assert.h" #include "gdb_string.h" -#include "i386-tdep.h" +#include "amd64-tdep.h" #include "i387-tdep.h" #include "record.h" #include <stdint.h> +#include "features/i386/i386.c" +#ifdef BFD64 +#include "features/i386/amd64.c" +#endif + /* Register names. */ -static char *i386_register_names[] = +static const char *i386_register_names[] = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", @@ -71,11 +76,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 +150,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 +2110,22 @@ i386_return_value (struct gdbarch *gdbarch, struct type *func_type, } \f -/* 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 +2166,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, @@ -5629,12 +5492,90 @@ 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; + const struct tdesc_feature *feature_core, *feature_vector; + int i, valid_p; + const char **register_names; + + int num_gregs; + int num_xmm_regs; + int num_core_regs; + int num_regs; /* If there is already a candidate, use it. */ arches = gdbarch_list_lookup_by_info (arches, &info); if (arches != NULL) return arches->gdbarch; + if (info.bfd_arch_info->arch != bfd_arch_i386) + return NULL; + + /* Get the x86 target description from INFO. We support both + 32bit and 64bit if BFD64 is defined. */ + tdesc = info.target_desc; + if (! tdesc_has_registers (tdesc)) + { + if (info.bfd_arch_info->bits_per_word == 32) + tdesc = tdesc_i386; + else +#ifdef BFD64 + tdesc = tdesc_amd64; +#else + return NULL; +#endif + } + + gdb_assert (tdesc_has_registers (tdesc)); + + /* Get core registers. */ + feature_core = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.core"); + if (feature_core == NULL) + return NULL; + + /* Get SSE registers. */ + feature_vector = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.sse"); + if (feature_vector == NULL) + return NULL; + + if (info.bfd_arch_info->bits_per_word == 32) + { + register_names = i386_register_names; + num_gregs = I386_NUM_GREGS; + /* I386_NUM_XREGS includes %mxcsr, so substract one. */ + num_xmm_regs = I386_NUM_XREGS - 1; + num_core_regs = I386_NUM_GREGS + I386_NUM_FREGS; + num_regs = I386_SSE_NUM_REGS; + } + else +#ifdef BFD64 + { + register_names = amd64_register_names; + num_gregs = AMD64_NUM_GREGS; + num_xmm_regs = 16; + num_core_regs = AMD64_NUM_GREGS + I386_NUM_FREGS; + /* Need to include %mxcsr, so add one. */ + num_regs = AMD64_NUM_GREGS + I386_NUM_FREGS + 16 + 1; + } +#else + return NULL; +#endif + + tdesc_data = tdesc_data_alloc (); + + valid_p = 1; + for (i = 0; i < num_core_regs; i++) + valid_p &= tdesc_numbered_register (feature_core, tdesc_data, i, + register_names[i]); + for (; i < num_regs; i++) + valid_p &= tdesc_numbered_register (feature_vector, tdesc_data, i, + register_names[i]); + if (!valid_p) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + /* Allocate space for the new architecture. */ tdep = XCALLOC (1, struct gdbarch_tdep); gdbarch = gdbarch_alloc (&info, tdep); @@ -5642,7 +5583,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* General-purpose registers. */ tdep->gregset = NULL; tdep->gregset_reg_offset = NULL; - tdep->gregset_num_regs = I386_NUM_GREGS; + tdep->gregset_num_regs = num_gregs; tdep->sizeof_gregset = 0; /* Floating-point registers. */ @@ -5670,8 +5611,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) of raw registers. */ tdep->mm0_regnum = 0; - /* I386_NUM_XREGS includes %mxcsr, so substract one. */ - tdep->num_xmm_regs = I386_NUM_XREGS - 1; + tdep->num_xmm_regs = num_xmm_regs; tdep->jb_pc_offset = -1; tdep->struct_return = pcc_struct_return; @@ -5698,9 +5638,12 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* 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); + set_gdbarch_num_regs (gdbarch, num_regs); + + set_tdesc_pseudo_register_type (gdbarch, i386_pseudo_register_type); + set_tdesc_pseudo_register_name (gdbarch, i386_pseudo_register_name); + + tdesc_use_registers (gdbarch, tdesc, tdesc_data); /* Register numbers of various important registers. */ set_gdbarch_sp_regnum (gdbarch, I386_ESP_REGNUM); /* %esp */ @@ -5882,4 +5825,10 @@ is \"default\"."), /* Initialize the i386-specific register groups. */ i386_init_reggroups (); + + /* Initialize the standard target descriptions. */ + initialize_tdesc_i386 (); +#ifdef BFD64 + initialize_tdesc_amd64 (); +#endif } diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h index 5915eb9..1ea81da 100644 --- a/gdb/i386-tdep.h +++ b/gdb/i386-tdep.h @@ -147,10 +147,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. */ @@ -240,10 +237,6 @@ enum record_i386_regnum #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 +256,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/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 ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-10 20:03 PATCH: Enable x86 XML target descriptions H.J. Lu @ 2010-02-17 14:59 ` H.J. Lu 2010-02-17 15:23 ` Mark Kettenis 2010-02-18 5:44 ` H.J. Lu 1 sibling, 1 reply; 39+ messages in thread From: H.J. Lu @ 2010-02-17 14:59 UTC (permalink / raw) To: H.J. Lu; +Cc: GDB 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? > > BTW, I have a followup patch to support al, ax and eax pseudo registers. > > Thanks. > > > H.J. > ---- > gdb/ > > 2010-02-10 H.J. Lu <hongjiu.lu@intel.com> > > * amd64-linux-nat.c (_initialize_amd64_linux_nat): Set > to_read_description to i386_linux_read_description. > * i386-linux-nat.c (_initialize_i386_linux_nat): Likewise. > > * amd64-linux-tdep.c (amd64_linux_register_name): Removed. > (amd64_linux_register_type): Likewise. > (amd64_linux_init_abi): Don't call set_gdbarch_num_regs, > set_gdbarch_register_name nor set_gdbarch_register_type. Call > i386_linux_init_orig_eax and set_gdbarch_core_read_description. > > * amd64-linux-tdep.h: Include "i386-linux-tdep.h". > > * amd64-tdep.c (amd64_register_names): Make it global. > (amd64_register_name): Removed. > (amd64_register_type): Likewise. > (amd64_init_abi): Don't call set_gdbarch_num_regs, > set_gdbarch_register_name nor set_gdbarch_register_type. > > * amd64-tdep.h (amd64_register_names): New. > > * i386-linux-tdep.c: Include "amd64-tdep.h" and > * "amd64-linux-tdep.h" instead "i386-tdep.h" and > "i386-linux-tdep.h". Include features/i386/i386-linux.c and > features/i386/amd64-linux.c. > (i386_linux_register_name): Support BFD64. > (i386_linux_register_type): New. > (i386_linux_init_orig_eax): Likewise. > (i386_linux_core_read_description): Likewise. > (i386_linux_read_description): Likewise. > (i386_linux_init_abi): Don't call set_gdbarch_num_regs nor > set_gdbarch_register_name. Call i386_linux_init_orig_eax and > set_gdbarch_core_read_description. > (_initialize_i386_linux_tdep): Call initialize_tdesc_i386_linux > and initialize_tdesc_x86_64_linux. > > * i386-linux-tdep.h (i386_linux_core_read_description): New. > (i386_linux_read_description): Likewise. > (i386_linux_init_orig_eax): Likewise. > > * i386-tdep.c: Include "amd64-tdep.h" instead of "i386-tdep.h". > Include features/i386/i386.c and features/i386/amd64.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): Support both 32bit and 64bit x86 target > descriptions. Don't call set_gdbarch_register_name nor > set_gdbarch_register_type. Call set_tdesc_pseudo_register_type, > set_tdesc_pseudo_register_name and tdesc_use_registers. > (_initialize_i386_tdep): Call initialize_tdesc_i386 and > initialize_tdesc_x86_64. > > * i386-tdep.h (gdbarch_tdep): Remove i386_eflags_type, > i386_mxcsr_type and i386_sse_type. > (i386_eflags_type): Removed. > (i386_mxcsr_type): Likewise. > (i386_mmx_type): Likewise. > (i386_sse_type): Likewise. > (i386_register_name): Likewise. > > * 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-10 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. > Any objections to enable XML target descriptions for x86? Any comments? Thanks. H.J. ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-17 14:59 ` H.J. Lu @ 2010-02-17 15:23 ` Mark Kettenis 2010-02-17 15:42 ` H.J. Lu 0 siblings, 1 reply; 39+ messages in thread From: Mark Kettenis @ 2010-02-17 15:23 UTC (permalink / raw) To: hjl.tools; +Cc: hjl.tools, gdb-patches > Date: Wed, 17 Feb 2010 06:58:20 -0800 > From: "H.J. Lu" <hongjiu.lu@intel.com> > > 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? > > > > BTW, I have a followup patch to support al, ax and eax pseudo registers. > > > > Thanks. > > > > > > H.J. > > ---- > > gdb/ > > > > 2010-02-10 H.J. Lu <hongjiu.lu@intel.com> > > > > * amd64-linux-nat.c (_initialize_amd64_linux_nat): Set > > to_read_description to i386_linux_read_description. > > * i386-linux-nat.c (_initialize_i386_linux_nat): Likewise. > > > > * amd64-linux-tdep.c (amd64_linux_register_name): Removed. > > (amd64_linux_register_type): Likewise. > > (amd64_linux_init_abi): Don't call set_gdbarch_num_regs, > > set_gdbarch_register_name nor set_gdbarch_register_type. Call > > i386_linux_init_orig_eax and set_gdbarch_core_read_description. > > > > * amd64-linux-tdep.h: Include "i386-linux-tdep.h". > > > > * amd64-tdep.c (amd64_register_names): Make it global. > > (amd64_register_name): Removed. > > (amd64_register_type): Likewise. > > (amd64_init_abi): Don't call set_gdbarch_num_regs, > > set_gdbarch_register_name nor set_gdbarch_register_type. > > > > * amd64-tdep.h (amd64_register_names): New. > > > > * i386-linux-tdep.c: Include "amd64-tdep.h" and > > * "amd64-linux-tdep.h" instead "i386-tdep.h" and > > "i386-linux-tdep.h". Include features/i386/i386-linux.c and > > features/i386/amd64-linux.c. > > (i386_linux_register_name): Support BFD64. > > (i386_linux_register_type): New. > > (i386_linux_init_orig_eax): Likewise. > > (i386_linux_core_read_description): Likewise. > > (i386_linux_read_description): Likewise. > > (i386_linux_init_abi): Don't call set_gdbarch_num_regs nor > > set_gdbarch_register_name. Call i386_linux_init_orig_eax and > > set_gdbarch_core_read_description. > > (_initialize_i386_linux_tdep): Call initialize_tdesc_i386_linux > > and initialize_tdesc_x86_64_linux. > > > > * i386-linux-tdep.h (i386_linux_core_read_description): New. > > (i386_linux_read_description): Likewise. > > (i386_linux_init_orig_eax): Likewise. > > > > * i386-tdep.c: Include "amd64-tdep.h" instead of "i386-tdep.h". > > Include features/i386/i386.c and features/i386/amd64.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): Support both 32bit and 64bit x86 target > > descriptions. Don't call set_gdbarch_register_name nor > > set_gdbarch_register_type. Call set_tdesc_pseudo_register_type, > > set_tdesc_pseudo_register_name and tdesc_use_registers. > > (_initialize_i386_tdep): Call initialize_tdesc_i386 and > > initialize_tdesc_x86_64. > > > > * i386-tdep.h (gdbarch_tdep): Remove i386_eflags_type, > > i386_mxcsr_type and i386_sse_type. > > (i386_eflags_type): Removed. > > (i386_mxcsr_type): Likewise. > > (i386_mmx_type): Likewise. > > (i386_sse_type): Likewise. > > (i386_register_name): Likewise. > > > > * 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-10 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. > > > > Any objections to enable XML target descriptions for x86? Any comments? Thanks for the reminder. I really dislike the fact that perfectly well understandable C code gets replaced by a complicated XML-based mechanism that I don't completely understand. So it is perfectly possible that there is some magic that I'm missing here, but I get the feeling that your diff breaks all native amd64 and i386 targets except for Linux. I'm afraid that isn't acceptable. Also, you should split i386_linux_register_name(), i386_linix_register_type() i386_linux_init_orig_eax() into seperate i386 and amd64 versions, and get rid of all the #ifdef BFD64's in the *-tdep.c files. There has been a clear split between 32-bit and 64-bit versions of the *-tdep.c code and this diff blurrs that. I can't comment on the gdbserver bits; that is Daniel's territory. ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-17 15:23 ` Mark Kettenis @ 2010-02-17 15:42 ` H.J. Lu 2010-02-17 15:46 ` Daniel Jacobowitz 0 siblings, 1 reply; 39+ messages in thread From: H.J. Lu @ 2010-02-17 15:42 UTC (permalink / raw) To: Mark Kettenis; +Cc: gdb-patches, Daniel Jacobowitz On Wed, Feb 17, 2010 at 7:22 AM, Mark Kettenis <mark.kettenis@xs4all.nl> wrote: >> Date: Wed, 17 Feb 2010 06:58:20 -0800 >> From: "H.J. Lu" <hongjiu.lu@intel.com> >> >> 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? >> > >> > BTW, I have a followup patch to support al, ax and eax pseudo registers. >> > >> > Thanks. >> > >> > >> > H.J. >> > ---- >> > gdb/ >> > >> > 2010-02-10 H.J. Lu <hongjiu.lu@intel.com> >> > >> > * amd64-linux-nat.c (_initialize_amd64_linux_nat): Set >> > to_read_description to i386_linux_read_description. >> > * i386-linux-nat.c (_initialize_i386_linux_nat): Likewise. >> > >> > * amd64-linux-tdep.c (amd64_linux_register_name): Removed. >> > (amd64_linux_register_type): Likewise. >> > (amd64_linux_init_abi): Don't call set_gdbarch_num_regs, >> > set_gdbarch_register_name nor set_gdbarch_register_type. Call >> > i386_linux_init_orig_eax and set_gdbarch_core_read_description. >> > >> > * amd64-linux-tdep.h: Include "i386-linux-tdep.h". >> > >> > * amd64-tdep.c (amd64_register_names): Make it global. >> > (amd64_register_name): Removed. >> > (amd64_register_type): Likewise. >> > (amd64_init_abi): Don't call set_gdbarch_num_regs, >> > set_gdbarch_register_name nor set_gdbarch_register_type. >> > >> > * amd64-tdep.h (amd64_register_names): New. >> > >> > * i386-linux-tdep.c: Include "amd64-tdep.h" and >> > * "amd64-linux-tdep.h" instead "i386-tdep.h" and >> > "i386-linux-tdep.h". Include features/i386/i386-linux.c and >> > features/i386/amd64-linux.c. >> > (i386_linux_register_name): Support BFD64. >> > (i386_linux_register_type): New. >> > (i386_linux_init_orig_eax): Likewise. >> > (i386_linux_core_read_description): Likewise. >> > (i386_linux_read_description): Likewise. >> > (i386_linux_init_abi): Don't call set_gdbarch_num_regs nor >> > set_gdbarch_register_name. Call i386_linux_init_orig_eax and >> > set_gdbarch_core_read_description. >> > (_initialize_i386_linux_tdep): Call initialize_tdesc_i386_linux >> > and initialize_tdesc_x86_64_linux. >> > >> > * i386-linux-tdep.h (i386_linux_core_read_description): New. >> > (i386_linux_read_description): Likewise. >> > (i386_linux_init_orig_eax): Likewise. >> > >> > * i386-tdep.c: Include "amd64-tdep.h" instead of "i386-tdep.h". >> > Include features/i386/i386.c and features/i386/amd64.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): Support both 32bit and 64bit x86 target >> > descriptions. Don't call set_gdbarch_register_name nor >> > set_gdbarch_register_type. Call set_tdesc_pseudo_register_type, >> > set_tdesc_pseudo_register_name and tdesc_use_registers. >> > (_initialize_i386_tdep): Call initialize_tdesc_i386 and >> > initialize_tdesc_x86_64. >> > >> > * i386-tdep.h (gdbarch_tdep): Remove i386_eflags_type, >> > i386_mxcsr_type and i386_sse_type. >> > (i386_eflags_type): Removed. >> > (i386_mxcsr_type): Likewise. >> > (i386_mmx_type): Likewise. >> > (i386_sse_type): Likewise. >> > (i386_register_name): Likewise. >> > >> > * 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-10 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. >> > >> >> Any objections to enable XML target descriptions for x86? Any comments? > > Thanks for the reminder. > > I really dislike the fact that perfectly well understandable C code > gets replaced by a complicated XML-based mechanism that I don't > completely understand. > > So it is perfectly possible that there is some magic that I'm missing > here, but I get the feeling that your diff breaks all native amd64 and > i386 targets except for Linux. I'm afraid that isn't acceptable. Can you try my patch on non-Linux x86 native targets? > Also, you should split i386_linux_register_name(), > i386_linix_register_type() i386_linux_init_orig_eax() into seperate > i386 and amd64 versions, and get rid of all the #ifdef BFD64's in the > *-tdep.c files. There has been a clear split between 32-bit and > 64-bit versions of the *-tdep.c code and this diff blurrs that. I am not sure it is easy to do, especially for register description. I have an impression that tdesc_use_registers should only be called once per arch. i386 and amd64 belong to the same bfd_arch_i386. That is how it is used in other places: arm-tdep.c: tdesc_use_registers (gdbarch, info.target_desc, tdesc_data); m68k-tdep.c: tdesc_use_registers (gdbarch, info.target_desc, tdesc_data); mips-tdep.c: tdesc_use_registers (gdbarch, info.target_desc, tdesc_data); rs6000-tdep.c: tdesc_use_registers (gdbarch, tdesc, tdesc_data); s390-tdep.c: tdesc_use_registers (gdbarch, tdesc, tdesc_data); There is only single call to tdesc_use_registers for 32bit/64bit mips/ppc. All other XML described tdep files support both 32bit/64bit: [hjl@gnu-6 gdb]$ ls mips*-tdep.c rs6000*-tdep.c ppc*-tdep.c mips64obsd-tdep.c mipsnbsd-tdep.c ppcnbsd-tdep.c rs6000-aix-tdep.c mips-irix-tdep.c mips-tdep.c ppcobsd-tdep.c rs6000-tdep.c mips-linux-tdep.c ppc-linux-tdep.c ppc-sysv-tdep.c I can try to minimize BFD64. But I am afraid that I can't totally avoid it. Is that acceptable? > I can't comment on the gdbserver bits; that is Daniel's territory. > Daniel, can you comment on gdbserver changes? Thanks. -- H.J. ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-17 15:42 ` H.J. Lu @ 2010-02-17 15:46 ` Daniel Jacobowitz 2010-02-17 16:19 ` Mark Kettenis 0 siblings, 1 reply; 39+ messages in thread From: Daniel Jacobowitz @ 2010-02-17 15:46 UTC (permalink / raw) To: H.J. Lu; +Cc: Mark Kettenis, gdb-patches On Wed, Feb 17, 2010 at 07:41:48AM -0800, H.J. Lu wrote: > > Also, you should split i386_linux_register_name(), > > i386_linix_register_type() i386_linux_init_orig_eax() into seperate > > i386 and amd64 versions, and get rid of all the #ifdef BFD64's in the > > *-tdep.c files. Â There has been a clear split between 32-bit and > > 64-bit versions of the *-tdep.c code and this diff blurrs that. > > I am not sure it is easy to do, especially for register description. > I have an impression that tdesc_use_registers should only be called > once per arch. i386 and amd64 belong to the same bfd_arch_i386. So? You can still call set_gdbarch_register_name. > I can try to minimize BFD64. But I am afraid that I can't totally avoid it. > Is that acceptable? No, amd64 support really should be in its own file. > > I can't comment on the gdbserver bits; that is Daniel's territory. > > > > Daniel, can you comment on gdbserver changes? Sorry, I will look at it as soon as I have time. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-17 15:46 ` Daniel Jacobowitz @ 2010-02-17 16:19 ` Mark Kettenis 0 siblings, 0 replies; 39+ messages in thread From: Mark Kettenis @ 2010-02-17 16:19 UTC (permalink / raw) To: dan; +Cc: hjl.tools, mark.kettenis, gdb-patches [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 1401 bytes --] > Date: Wed, 17 Feb 2010 10:45:54 -0500 > From: Daniel Jacobowitz <dan@codesourcery.com> > > On Wed, Feb 17, 2010 at 07:41:48AM -0800, H.J. Lu wrote: > > > Also, you should split i386_linux_register_name(), > > > i386_linix_register_type() i386_linux_init_orig_eax() into seperate > > > i386 and amd64 versions, and get rid of all the #ifdef BFD64's in the > > > *-tdep.c files. There has been a clear split between 32-bit and > > > 64-bit versions of the *-tdep.c code and this diff blurrs that. > > > > I am not sure it is easy to do, especially for register description. > > I have an impression that tdesc_use_registers should only be called > > once per arch. i386 and amd64 belong to the same bfd_arch_i386. > > So? You can still call set_gdbarch_register_name. > > > I can try to minimize BFD64. But I am afraid that I can't totally avoid it. > > Is that acceptable? > > No, amd64 support really should be in its own file. So I guess a potential way of handling this, is to leave the set_gdbarch_num_regs/set_gdbarch_register_name/set_gdbarch_register_type calls as they are now, add a tdesc member to "struct gdbarch_tdep", initialize that in the xxx_init_abi() functions (if a target description is available), possibly overriding a less-specific setting, and call tdesc_use_registers at the very end of i386_gdbarch_init() if the tdesc member of "struct gdbarch_tdep" is non-NULL. ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-10 20:03 PATCH: Enable x86 XML target descriptions H.J. Lu 2010-02-17 14:59 ` H.J. Lu @ 2010-02-18 5:44 ` H.J. Lu 2010-02-18 15:37 ` H.J. Lu 1 sibling, 1 reply; 39+ messages in thread From: H.J. Lu @ 2010-02-18 5:44 UTC (permalink / raw) To: H.J. Lu; +Cc: GDB 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. H.J. ---- gdb/ 2010-02-17 H.J. Lu <hongjiu.lu@intel.com> * amd64-linux-nat.c: Include "i387-tdep.h". (amd64_linux_read_description): New. (_initialize_amd64_linux_nat): Set to_read_description to amd64_linux_read_description. * amd64-linux-tdep.c: Include "i387-tdep.h" and "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 "i387-tdep.h" and * "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_SSE_NUM_REGS): Replace I386_NUM_FREGS with I387_NUM_REGS. * 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-17 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. diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c index 5c9e558..b325368 100644 --- a/gdb/amd64-linux-nat.c +++ b/gdb/amd64-linux-nat.c @@ -48,6 +48,7 @@ #include "gregset.h" #include "amd64-tdep.h" +#include "i387-tdep.h" #include "i386-linux-tdep.h" #include "amd64-nat.h" #include "i386-nat.h" @@ -674,6 +675,14 @@ amd64_linux_siginfo_fixup (struct siginfo *native, gdb_byte *inf, int direction) return 0; } +/* Get Linux/x86 target description from running target. */ + +static const struct target_desc * +amd64_linux_read_description (struct target_ops *ops) +{ + return tdesc_amd64_linux; +} + /* Provide a prototype to silence -Wmissing-prototypes. */ void _initialize_amd64_linux_nat (void); @@ -712,6 +721,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..708801f 100644 --- a/gdb/amd64-linux-tdep.c +++ b/gdb/amd64-linux-tdep.c @@ -34,9 +34,12 @@ #include "gdb_string.h" #include "amd64-tdep.h" +#include "i387-tdep.h" #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 +237,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 +1243,39 @@ 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; + + switch (bfd_section_size (abfd, section)) + { + case 0x200: + /* Linux/x86-64. */ + return tdesc_amd64_linux; + default: + return NULL; + } +} + +/* Get Linux/x86 target description from running target. */ 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); @@ -1282,10 +1294,31 @@ 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); + + /* Reserve a number for orig_rax. */ 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); + + 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) + { + tdep->tdesc = NULL; + return; + } + + valid_p = tdesc_numbered_register (feature, tdesc_data, + AMD64_LINUX_ORIG_RAX_REGNUM, + "orig_rax"); + if (!valid_p) + { + tdep->tdesc = NULL; + return; + } + + tdep->register_reggroup_p = amd64_linux_register_reggroup_p; /* Functions for 'catch syscall'. */ set_xml_syscall_file_name (XML_SYSCALL_FILENAME_AMD64); @@ -1299,6 +1332,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 +1528,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..8f5817c 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; + tdep->num_core_regs = AMD64_NUM_GREGS + I387_NUM_REGS; + tdep->register_names = amd64_register_names; + + if (! tdesc_has_registers (tdesc)) + tdesc = tdesc_amd64; + tdep->tdesc = tdesc; + /* 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 (); +} \f /* 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..43b3b7c 100644 --- a/gdb/i386-linux-tdep.c +++ b/gdb/i386-linux-tdep.c @@ -30,6 +30,7 @@ #include "gdb_string.h" #include "i386-tdep.h" +#include "i387-tdep.h" #include "i386-linux-tdep.h" #include "linux-tdep.h" #include "glibc-tdep.h" @@ -46,6 +47,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 +58,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,10 +561,38 @@ 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; + + switch (bfd_section_size (abfd, section)) + { + case 0x6c: + /* Linux/i386. */ + return tdesc_i386_linux; + default: + return NULL; + } +} + 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); @@ -582,9 +601,31 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) to adjust a few things. */ set_gdbarch_write_pc (gdbarch, i386_linux_write_pc); + + /* Reserve a number for orig_eax. */ 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); + + 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) + { + tdep->tdesc = NULL; + return; + } + + valid_p = tdesc_numbered_register (feature, tdesc_data, + I386_LINUX_ORIG_EAX_REGNUM, + "orig_eax"); + if (!valid_p) + { + tdep->tdesc = NULL; + return; + } + + 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 +824,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 +852,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..12b6d7e 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, } \f -/* 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, @@ -5629,12 +5489,20 @@ 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; + const struct tdesc_feature *feature_core, *feature_vector; + int num_regs; + int i, valid_p; /* If there is already a candidate, use it. */ arches = gdbarch_list_lookup_by_info (arches, &info); if (arches != NULL) return arches->gdbarch; + if (info.bfd_arch_info->arch != bfd_arch_i386) + return NULL; + /* Allocate space for the new architecture. */ tdep = XCALLOC (1, struct gdbarch_tdep); gdbarch = gdbarch_alloc (&info, tdep); @@ -5649,6 +5517,9 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->fpregset = NULL; tdep->sizeof_fpregset = I387_SIZEOF_FSAVE; + tdep->num_core_regs = I386_NUM_GREGS + I387_NUM_REGS; + tdep->register_names = i386_register_names; + /* The default settings include the FPU registers, the MMX registers and the SSE registers. This can be overridden for a specific ABI by adjusting the members `st0_regnum', `mm0_regnum' and @@ -5696,12 +5567,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 +5637,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 +5645,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 +5663,80 @@ 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; + + 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 (! tdesc_has_registers (tdesc)) + { + xfree (tdep); + gdbarch_free (gdbarch); + return NULL; + } + + /* 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) + { + xfree (tdep); + gdbarch_free (gdbarch); + return NULL; + } + + 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]); + + if (!valid_p) + { + 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 +5813,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..b667237 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. */ @@ -230,20 +239,15 @@ 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 \ +#define I386_SSE_NUM_REGS (I386_NUM_GREGS + I387_NUM_REGS \ + I386_NUM_XREGS) /* 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 ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-18 5:44 ` H.J. Lu @ 2010-02-18 15:37 ` H.J. Lu 2010-02-18 23:01 ` H.J. Lu 0 siblings, 1 reply; 39+ messages in thread From: H.J. Lu @ 2010-02-18 15:37 UTC (permalink / raw) To: GDB 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? Thanks. H.J. --- gdb/ 2010-02-17 H.J. Lu <hongjiu.lu@intel.com> * amd64-linux-nat.c (amd64_linux_read_description): New. (_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-17 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. diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c index 5c9e558..d4d263b 100644 --- a/gdb/amd64-linux-nat.c +++ b/gdb/amd64-linux-nat.c @@ -674,6 +674,14 @@ amd64_linux_siginfo_fixup (struct siginfo *native, gdb_byte *inf, int direction) return 0; } +/* Get Linux/x86 target description from running target. */ + +static const struct target_desc * +amd64_linux_read_description (struct target_ops *ops) +{ + return tdesc_amd64_linux; +} + /* Provide a prototype to silence -Wmissing-prototypes. */ void _initialize_amd64_linux_nat (void); @@ -712,6 +720,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..4de95a3 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,39 @@ 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; + + switch (bfd_section_size (abfd, section)) + { + case 0x200: + /* Linux/x86-64. */ + return tdesc_amd64_linux; + default: + return NULL; + } +} + +/* Get Linux/x86 target description from running target. */ 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); @@ -1282,10 +1293,31 @@ 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); + + /* Reserve a number for orig_rax. */ 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); + + 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) + { + tdep->tdesc = NULL; + return; + } + + valid_p = tdesc_numbered_register (feature, tdesc_data, + AMD64_LINUX_ORIG_RAX_REGNUM, + "orig_rax"); + if (!valid_p) + { + tdep->tdesc = NULL; + return; + } + + tdep->register_reggroup_p = amd64_linux_register_reggroup_p; /* Functions for 'catch syscall'. */ set_xml_syscall_file_name (XML_SYSCALL_FILENAME_AMD64); @@ -1299,6 +1331,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 +1527,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..8f5817c 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; + tdep->num_core_regs = AMD64_NUM_GREGS + I387_NUM_REGS; + tdep->register_names = amd64_register_names; + + if (! tdesc_has_registers (tdesc)) + tdesc = tdesc_amd64; + tdep->tdesc = tdesc; + /* 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 (); +} \f /* 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..5448eb4 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,10 +560,38 @@ 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; + + switch (bfd_section_size (abfd, section)) + { + case 0x6c: + /* Linux/i386. */ + return tdesc_i386_linux; + default: + return NULL; + } +} + 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); @@ -582,9 +600,31 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) to adjust a few things. */ set_gdbarch_write_pc (gdbarch, i386_linux_write_pc); + + /* Reserve a number for orig_eax. */ 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); + + 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) + { + tdep->tdesc = NULL; + return; + } + + valid_p = tdesc_numbered_register (feature, tdesc_data, + I386_LINUX_ORIG_EAX_REGNUM, + "orig_eax"); + if (!valid_p) + { + tdep->tdesc = NULL; + return; + } + + 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 +823,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 +851,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..a474f69 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, } \f -/* 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, @@ -5629,12 +5489,20 @@ 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; + const struct tdesc_feature *feature_core, *feature_vector; + int num_regs; + int i, valid_p; /* If there is already a candidate, use it. */ arches = gdbarch_list_lookup_by_info (arches, &info); if (arches != NULL) return arches->gdbarch; + if (info.bfd_arch_info->arch != bfd_arch_i386) + return NULL; + /* Allocate space for the new architecture. */ tdep = XCALLOC (1, struct gdbarch_tdep); gdbarch = gdbarch_alloc (&info, tdep); @@ -5649,6 +5517,9 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->fpregset = NULL; tdep->sizeof_fpregset = I387_SIZEOF_FSAVE; + tdep->num_core_regs = I386_NUM_GREGS + I387_NUM_REGS; + tdep->register_names = i386_register_names; + /* The default settings include the FPU registers, the MMX registers and the SSE registers. This can be overridden for a specific ABI by adjusting the members `st0_regnum', `mm0_regnum' and @@ -5696,12 +5567,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 +5637,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 +5645,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 +5663,79 @@ 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; + + 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 (! tdesc_has_registers (tdesc)) + { + xfree (tdep); + gdbarch_free (gdbarch); + return NULL; + } + + /* 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) + { + xfree (tdep); + gdbarch_free (gdbarch); + return NULL; + } + + 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]); + + if (!valid_p) + { + 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 +5812,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 ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-18 15:37 ` H.J. Lu @ 2010-02-18 23:01 ` H.J. Lu 2010-02-22 13:42 ` Mark Kettenis 2010-02-22 21:04 ` H.J. Lu 0 siblings, 2 replies; 39+ messages in thread From: H.J. Lu @ 2010-02-18 23:01 UTC (permalink / raw) To: H.J. Lu; +Cc: GDB 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. H.J. --- gdb/ 2010-02-17 H.J. Lu <hongjiu.lu@intel.com> * amd64-linux-nat.c (amd64_linux_read_description): New. (_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-17 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. diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c index 5c9e558..8038555 100644 --- a/gdb/amd64-linux-nat.c +++ b/gdb/amd64-linux-nat.c @@ -674,6 +674,17 @@ amd64_linux_siginfo_fixup (struct siginfo *native, gdb_byte *inf, int direction) return 0; } +/* Get Linux/x86 target description from running target. */ + +static const struct target_desc * +amd64_linux_read_description (struct target_ops *ops) +{ + if (gdbarch_ptr_bit (target_gdbarch) == 64) + return tdesc_amd64_linux; + else + return tdesc_i386_linux; +} + /* Provide a prototype to silence -Wmissing-prototypes. */ void _initialize_amd64_linux_nat (void); @@ -712,6 +723,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..d0fad7a 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,38 @@ 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; + + switch (bfd_section_size (abfd, section)) + { + case 0x200: + /* Linux/x86-64. */ + return tdesc_amd64_linux; + default: + return NULL; + } +} + 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); @@ -1282,10 +1292,31 @@ 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); + + /* Reserve a number for orig_rax. */ 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); + + 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) + { + tdep->tdesc = NULL; + return; + } + + valid_p = tdesc_numbered_register (feature, tdesc_data, + AMD64_LINUX_ORIG_RAX_REGNUM, + "orig_rax"); + if (!valid_p) + { + tdep->tdesc = NULL; + return; + } + + tdep->register_reggroup_p = amd64_linux_register_reggroup_p; /* Functions for 'catch syscall'. */ set_xml_syscall_file_name (XML_SYSCALL_FILENAME_AMD64); @@ -1299,6 +1330,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 +1526,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 (); +} \f /* 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..5448eb4 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,10 +560,38 @@ 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; + + switch (bfd_section_size (abfd, section)) + { + case 0x6c: + /* Linux/i386. */ + return tdesc_i386_linux; + default: + return NULL; + } +} + 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); @@ -582,9 +600,31 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) to adjust a few things. */ set_gdbarch_write_pc (gdbarch, i386_linux_write_pc); + + /* Reserve a number for orig_eax. */ 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); + + 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) + { + tdep->tdesc = NULL; + return; + } + + valid_p = tdesc_numbered_register (feature, tdesc_data, + I386_LINUX_ORIG_EAX_REGNUM, + "orig_eax"); + if (!valid_p) + { + tdep->tdesc = NULL; + return; + } + + 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 +823,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 +851,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..5b46625 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, } \f -/* 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, @@ -5629,6 +5489,11 @@ 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; + const struct tdesc_feature *feature_core, *feature_vector; + int num_regs; + int i, valid_p; /* If there is already a candidate, use it. */ arches = gdbarch_list_lookup_by_info (arches, &info); @@ -5696,12 +5561,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 +5631,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 +5639,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 +5657,82 @@ 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 (! tdesc_has_registers (tdesc)) + { + xfree (tdep); + gdbarch_free (gdbarch); + return NULL; + } + + /* 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) + { + xfree (tdep); + gdbarch_free (gdbarch); + return NULL; + } + + 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]); + + if (!valid_p) + { + 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 ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-18 23:01 ` H.J. Lu @ 2010-02-22 13:42 ` Mark Kettenis 2010-02-22 14:17 ` H.J. Lu 2010-02-22 14:41 ` Daniel Jacobowitz 2010-02-22 21:04 ` H.J. Lu 1 sibling, 2 replies; 39+ messages in thread From: Mark Kettenis @ 2010-02-22 13:42 UTC (permalink / raw) To: hjl.tools; +Cc: hjl.tools, gdb-patches > Date: Thu, 18 Feb 2010 15:01:35 -0800 > From: "H.J. Lu" <hongjiu.lu@intel.com> > > 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. I tested a GDB with this diff on OpenBSD/i386 and only noticed one regression: Running ./gdb.xml/tdesc-regs.exp ... -PASS: gdb.xml/tdesc-regs.exp: set tdesc file single-reg.xml +FAIL: gdb.xml/tdesc-regs.exp: set tdesc file single-reg.xml To me it looks like this test needs to be adjusted now that the i386 target has tdesc support. I still need a bit more time to review the diff. I'm sorry, but the tdesc stuff is something I'm simply not familiar with, so it takes some time to understand the implications of this diff. However, below are some questions/issues I ran into already. > diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c > index 5c9e558..8038555 100644 > --- a/gdb/amd64-linux-nat.c > +++ b/gdb/amd64-linux-nat.c > @@ -674,6 +674,17 @@ amd64_linux_siginfo_fixup (struct siginfo *native, gdb_byte *inf, int direction) > return 0; > } > > +/* Get Linux/x86 target description from running target. */ > + > +static const struct target_desc * > +amd64_linux_read_description (struct target_ops *ops) > +{ > + if (gdbarch_ptr_bit (target_gdbarch) == 64) > + return tdesc_amd64_linux; > + else > + return tdesc_i386_linux; > +} > + This made me wonder what happens if you attach to a process without loading an executable first. Currently this works, since GDB can figure out what executable belongs to the the process and load the executable automatically. But I fear a chicken & egg problem here: the gdbarch is derviced from the tdesc, but in order to determine the tdesc you need a gdbarch. > @@ -1260,10 +1242,38 @@ 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; > + > + switch (bfd_section_size (abfd, section)) > + { > + case 0x200: > + /* Linux/x86-64. */ > + return tdesc_amd64_linux; > + default: > + return NULL; > + } > +} This seems a bit odd to me. I'd expect this function to just return tdesc_amd64_linux unconditionally. > @@ -1282,10 +1292,31 @@ 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); > + > + /* Reserve a number for orig_rax. */ > 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); Why do you need to set num_regs here, but not the register_name, register_type and register_reggroup_p members? All four are set by tdesc_use_registers(). > + > + if (! tdesc_has_registers (tdesc)) > + tdesc = tdesc_amd64_linux; > + tdep->tdesc = tdesc; > + > + feature = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.linux"); Shouldn't that be org.gnu.gdb.amd64.linux? > @@ -2112,87 +2107,22 @@ i386_return_value (struct gdbarch *gdbarch, struct type *func_type, > } > \f > > -/* 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; > -} I didn't realize these functions would effectively be moved into target-descriptions.c. That feels wrong. > + /* Target description may be changed. */ > + tdesc = tdep->tdesc; > + > + if (! tdesc_has_registers (tdesc)) > + { > + xfree (tdep); > + gdbarch_free (gdbarch); > + return NULL; > + } > + > + /* 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) > + { > + xfree (tdep); > + gdbarch_free (gdbarch); > + return NULL; > + } > + > + 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]); > + > + if (!valid_p) > + { > + tdesc_data_cleanup (tdesc_data); > + xfree (tdep); > + gdbarch_free (gdbarch); > + return NULL; > + } That's quite a bit of code to verify the sanity of the target description. I think that should go into a seperate function. > + > + 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); Why is it necessary to do this? ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-22 13:42 ` Mark Kettenis @ 2010-02-22 14:17 ` H.J. Lu 2010-02-22 15:01 ` Mark Kettenis 2010-02-28 20:30 ` Mark Kettenis 2010-02-22 14:41 ` Daniel Jacobowitz 1 sibling, 2 replies; 39+ messages in thread From: H.J. Lu @ 2010-02-22 14:17 UTC (permalink / raw) To: Mark Kettenis; +Cc: gdb-patches On Mon, Feb 22, 2010 at 5:42 AM, Mark Kettenis <mark.kettenis@xs4all.nl> wrote: >> Date: Thu, 18 Feb 2010 15:01:35 -0800 >> From: "H.J. Lu" <hongjiu.lu@intel.com> >> >> 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. > > I tested a GDB with this diff on OpenBSD/i386 and only noticed one > regression: > > Running ./gdb.xml/tdesc-regs.exp ... > -PASS: gdb.xml/tdesc-regs.exp: set tdesc file single-reg.xml > +FAIL: gdb.xml/tdesc-regs.exp: set tdesc file single-reg.xml > > To me it looks like this test needs to be adjusted now that the i386 > target has tdesc support. I will do that. > I still need a bit more time to review the diff. I'm sorry, but the > tdesc stuff is something I'm simply not familiar with, so it takes > some time to understand the implications of this diff. However, below > are some questions/issues I ran into already. > >> diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c >> index 5c9e558..8038555 100644 >> --- a/gdb/amd64-linux-nat.c >> +++ b/gdb/amd64-linux-nat.c >> @@ -674,6 +674,17 @@ amd64_linux_siginfo_fixup (struct siginfo *native, gdb_byte *inf, int direction) >> return 0; >> } >> >> +/* Get Linux/x86 target description from running target. */ >> + >> +static const struct target_desc * >> +amd64_linux_read_description (struct target_ops *ops) >> +{ >> + if (gdbarch_ptr_bit (target_gdbarch) == 64) >> + return tdesc_amd64_linux; >> + else >> + return tdesc_i386_linux; >> +} >> + > > This made me wonder what happens if you attach to a process without > loading an executable first. Currently this works, since GDB can > figure out what executable belongs to the the process and load the > executable automatically. But I fear a chicken & egg problem here: > the gdbarch is derviced from the tdesc, but in order to determine the > tdesc you need a gdbarch. How do you attach to a process without loading an executable first? Gdb has to load something to debug. Do you have a testcase? I will fix it if it doesn't work already. >> @@ -1260,10 +1242,38 @@ 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; >> + >> + switch (bfd_section_size (abfd, section)) >> + { >> + case 0x200: >> + /* Linux/x86-64. */ >> + return tdesc_amd64_linux; >> + default: >> + return NULL; >> + } >> +} > > This seems a bit odd to me. I'd expect this function to just return > tdesc_amd64_linux unconditionally. The folowup patch for AVX will change it to xcr0 = i386_linux_core_read_xcr0 (gdbarch, target, abfd); switch (bfd_section_size (abfd, section)) { case 0x200: /* Linux/x86-64. */ if ((xcr0 & XSTATE_AVX_MASK) == XSTATE_AVX_MASK) return tdesc_amd64_avx_linux; else return tdesc_amd64_linux; default: return NULL; } Other OSes will need a similar change to support AVX. >> @@ -1282,10 +1292,31 @@ 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); >> + >> + /* Reserve a number for orig_rax. */ >> 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); > > Why do you need to set num_regs here, but not the register_name, > register_type and register_reggroup_p members? All four are set by > tdesc_use_registers(). tdesc_use_registers is called after amd64_linux_init_abi. At this point, num_regs is incorrect for Linux. We need to update it for valid_p = tdesc_numbered_register (feature, tdesc_data, AMD64_LINUX_ORIG_RAX_REGNUM, "orig_rax"); >> + >> + if (! tdesc_has_registers (tdesc)) >> + tdesc = tdesc_amd64_linux; >> + tdep->tdesc = tdesc; >> + >> + feature = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.linux"); > > Shouldn't that be org.gnu.gdb.amd64.linux? 64bit-core.xml and 64bit-sse.xml have <feature name="org.gnu.gdb.i386.core"> and <feature name="org.gnu.gdb.i386.sse"> so that i386_gdbarch_init can have /* 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"); after /* Hook in ABI-specific overrides, if they have been registered. */ info.tdep_info = (void *) tdesc_data; gdbarch_init_osabi (info, gdbarch); It will be odd for 64bit-linux.xml to have <feature name="org.gnu.gdb.i386.linux"> >> @@ -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; >> -} > > I didn't realize these functions would effectively be moved into > target-descriptions.c. That feels wrong. That is how target description works. All types used in XML are supported in target-descriptions.c. >> + /* Target description may be changed. */ >> + tdesc = tdep->tdesc; >> + >> + if (! tdesc_has_registers (tdesc)) >> + { >> + xfree (tdep); >> + gdbarch_free (gdbarch); >> + return NULL; >> + } >> + >> + /* 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) >> + { >> + xfree (tdep); >> + gdbarch_free (gdbarch); >> + return NULL; >> + } >> + >> + 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]); >> + >> + if (!valid_p) >> + { >> + tdesc_data_cleanup (tdesc_data); >> + xfree (tdep); >> + gdbarch_free (gdbarch); >> + return NULL; >> + } > > That's quite a bit of code to verify the sanity of the target description. I think that should go into a seperate function. I will do that. >> + >> + 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); > > Why is it necessary to do this? > i386_gdbarch_init calls 1. gdbarch_init_osabi 2. tdesc_use_registers, which calls set_gdbarch_register_reggroup_p (gdbarch, tdesc_register_reggroup_p); If you want to change register_reggroup_p in gdbarch_init_osabi, you have to store it in tdep and call set_gdbarch_register_reggroup_p after tdesc_use_registers. Thanks. -- H.J. ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-22 14:17 ` H.J. Lu @ 2010-02-22 15:01 ` Mark Kettenis 2010-02-22 15:27 ` H.J. Lu 2010-02-28 20:30 ` Mark Kettenis 1 sibling, 1 reply; 39+ messages in thread From: Mark Kettenis @ 2010-02-22 15:01 UTC (permalink / raw) To: hjl.tools; +Cc: gdb-patches [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 1025 bytes --] > Date: Mon, 22 Feb 2010 06:17:29 -0800 > From: "H.J. Lu" <hjl.tools@gmail.com> > > >> +/* Get Linux/x86 target description from running target. */ > >> + > >> +static const struct target_desc * > >> +amd64_linux_read_description (struct target_ops *ops) > >> +{ > >> + if (gdbarch_ptr_bit (target_gdbarch) == 64) > >> + return tdesc_amd64_linux; > >> + else > >> + return tdesc_i386_linux; > >> +} > >> + > > > > This made me wonder what happens if you attach to a process without > > loading an executable first. Currently this works, since GDB can > > figure out what executable belongs to the the process and load the > > executable automatically. But I fear a chicken & egg problem here: > > the gdbarch is derviced from the tdesc, but in order to determine the > > tdesc you need a gdbarch. > > How do you attach to a process without loading an executable first? > Gdb has to load something to debug. Do you have a testcase? I will > fix it if it doesn't work already. $ gdb ... (gdb) attach PID ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-22 15:01 ` Mark Kettenis @ 2010-02-22 15:27 ` H.J. Lu 2010-02-22 15:30 ` Daniel Jacobowitz 0 siblings, 1 reply; 39+ messages in thread From: H.J. Lu @ 2010-02-22 15:27 UTC (permalink / raw) To: Mark Kettenis; +Cc: gdb-patches On Mon, Feb 22, 2010 at 7:01 AM, Mark Kettenis <mark.kettenis@xs4all.nl> wrote: >> Date: Mon, 22 Feb 2010 06:17:29 -0800 >> From: "H.J. Lu" <hjl.tools@gmail.com> >> >> >> +/* Get Linux/x86 target description from running target. */ >> >> + >> >> +static const struct target_desc * >> >> +amd64_linux_read_description (struct target_ops *ops) >> >> +{ >> >> + if (gdbarch_ptr_bit (target_gdbarch) == 64) >> >> + return tdesc_amd64_linux; >> >> + else >> >> + return tdesc_i386_linux; >> >> +} >> >> + >> > >> > This made me wonder what happens if you attach to a process without >> > loading an executable first. Currently this works, since GDB can >> > figure out what executable belongs to the the process and load the >> > executable automatically. But I fear a chicken & egg problem here: >> > the gdbarch is derviced from the tdesc, but in order to determine the >> > tdesc you need a gdbarch. >> >> How do you attach to a process without loading an executable first? >> Gdb has to load something to debug. Do you have a testcase? I will >> fix it if it doesn't work already. > > $ gdb > ... > (gdb) attach PID > > It works fine. amd64_linux_read_description is called via (gdb) att 20026 Attaching to process 20026 Reading symbols from /export/home/hjl/bugs/gdb/xml/p...done. Detaching after fork from child process 20039. Breakpoint 3, amd64_linux_read_description (ops=0xa94900) at /export/gnu/import/git/gdb-avx/gdb/amd64-linux-nat.c:681 681 { Missing separate debuginfos, use: debuginfo-install expat-2.0.1-8.fc12.x86_64 glibc-2.11.1-2.2.f12.x86_64 ncurses-libs-5.7-3.20090207.fc12.x86_64 python-2.6.2-2.fc12.x86_64 python-libs-2.6.2-2.fc12.x86_64 zlib-1.2.3-23.fc12.x86_64 (top-gdb) bt #0 amd64_linux_read_description (ops=0xa94900) at /export/gnu/import/git/gdb-avx/gdb/amd64-linux-nat.c:681 #1 0x000000000054be91 in target_read_description ( target=<value optimized out>) at /export/gnu/import/git/gdb-avx/gdb/target.c:2252 #2 0x00000000005c423a in target_find_description () at /export/gnu/import/git/gdb-avx/gdb/target-descriptions.c:279 #3 0x000000000051e266 in post_create_inferior (target=0xa74be0, from_tty=1) at /export/gnu/import/git/gdb-avx/gdb/infcmd.c:402 #4 0x000000000051e36f in attach_command_post_wait ( args=<value optimized out>, from_tty=1, async_exec=0) at /export/gnu/import/git/gdb-avx/gdb/infcmd.c:2249 #5 0x000000000051e7fd in attach_command (args=0xa77104 "20026", from_tty=1) at /export/gnu/import/git/gdb-avx/gdb/infcmd.c:2426 #6 0x00000000004559eb in execute_command (p=0xa77108 "6", from_tty=1) at /export/gnu/import/git/gdb-avx/gdb/top.c:441 #7 0x0000000000535947 in command_handler (command=0xa77100 "") at /export/gnu/import/git/gdb-avx/gdb/event-top.c:511 #8 0x0000000000536564 in command_line_handler (rl=<value optimized out>) at /export/gnu/import/git/gdb-avx/gdb/event-top.c:736 #9 0x00000000005fb487 in rl_callback_read_char () at /export/gnu/import/git/gdb-avx/readline/callback.c:205 #10 0x0000000000535a79 in rl_callback_read_char_wrapper ( ---Type <return> to continue, or q <return> to quit--- client_data=<value optimized out>) at /export/gnu/import/git/gdb-avx/gdb/event-top.c:178 #11 0x00000000005343a8 in process_event () at /export/gnu/import/git/gdb-avx/gdb/event-loop.c:393 #12 0x00000000005354da in gdb_do_one_event (data=<value optimized out>) at /export/gnu/import/git/gdb-avx/gdb/event-loop.c:458 #13 0x000000000052f75b in catch_errors (func=<value optimized out>, func_args=<value optimized out>, errstring=<value optimized out>, mask=<value optimized out>) at /export/gnu/import/git/gdb-avx/gdb/exceptions.c:510 #14 0x00000000004bf610 in tui_command_loop (data=<value optimized out>) at /export/gnu/import/git/gdb-avx/gdb/tui/tui-interp.c:154 #15 0x000000000044d489 in captured_command_loop (data=<value optimized out>) at /export/gnu/import/git/gdb-avx/gdb/main.c:226 #16 0x000000000052f75b in catch_errors (func=<value optimized out>, func_args=<value optimized out>, errstring=<value optimized out>, mask=<value optimized out>) at /export/gnu/import/git/gdb-avx/gdb/exceptions.c:510 #17 0x000000000044cebe in captured_main (data=<value optimized out>) at /export/gnu/import/git/gdb-avx/gdb/main.c:905 #18 0x000000000052f75b in catch_errors (func=<value optimized out>, func_args=<value optimized out>, errstring=<value optimized out>, mask=<value optimized out>) ---Type <return> to continue, or q <return> to quit--- at /export/gnu/import/git/gdb-avx/gdb/exceptions.c:510 #19 0x000000000044c354 in gdb_main (args=0x0) at /export/gnu/import/git/gdb-avx/gdb/main.c:914 #20 0x000000000044c31e in main (argc=10957472, argv=<value optimized out>) at /export/gnu/import/git/gdb-avx/gdb/gdb.c:33 (top-gdb) -- H.J. ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-22 15:27 ` H.J. Lu @ 2010-02-22 15:30 ` Daniel Jacobowitz 2010-02-22 15:39 ` H.J. Lu 0 siblings, 1 reply; 39+ messages in thread From: Daniel Jacobowitz @ 2010-02-22 15:30 UTC (permalink / raw) To: H.J. Lu; +Cc: Mark Kettenis, gdb-patches On Mon, Feb 22, 2010 at 07:27:30AM -0800, H.J. Lu wrote: > It works fine. amd64_linux_read_description is called via Does it work fine for the right reason? gdbarch has not been set yet. How can the gdbarch know if the PID is a 32-bit or 64-bit process? -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-22 15:30 ` Daniel Jacobowitz @ 2010-02-22 15:39 ` H.J. Lu 0 siblings, 0 replies; 39+ messages in thread From: H.J. Lu @ 2010-02-22 15:39 UTC (permalink / raw) To: H.J. Lu, Mark Kettenis, gdb-patches On Mon, Feb 22, 2010 at 7:29 AM, Daniel Jacobowitz <dan@codesourcery.com> wrote: > On Mon, Feb 22, 2010 at 07:27:30AM -0800, H.J. Lu wrote: >> It works fine. amd64_linux_read_description is called via > > Does it work fine for the right reason? gdbarch has not been set yet. > How can the gdbarch know if the PID is a 32-bit or 64-bit process? > From (gdb) att 20196 Attaching to process 20196 Reading symbols from /export/home/hjl/bugs/gdb/xml/p...done. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Detaching after fork from child process 20207. Breakpoint 3, amd64_linux_read_description (ops=0xa94900) at /export/gnu/import/git/gdb-avx/gdb/amd64-linux-nat.c:681 681 { Missing separate debuginfos, use: debuginfo-install expat-2.0.1-8.fc12.x86_64 ncurses-libs-5.7-3.20090207.fc12.x86_64 python-2.6.2-2.fc12.x86_64 python-libs-2.6.2-2.fc12.x86_64 zlib-1.2.3-23.fc12.x86_64 (top-gdb) p target_gdbarch $1 = (struct gdbarch *) 0xbb3660 (top-gdb) p *target_gdbarch $2 = {initialized_p = 1, obstack = 0xbb35f0, bfd_arch_info = 0x7bd0a0, byte_order = 1, byte_order_for_code = 1, osabi = GDB_OSABI_LINUX, target_desc = 0x0, tdep = 0xbb3500, dump_tdep = 0, nr_data = 18, data = 0xbb3a30, swap = 0x0, bits_big_endian = 0, short_bit = 16, int_bit = 32, long_bit = 32, long_long_bit = 64, float_bit = 32, float_format = 0xa4e6e0, double_bit = 64, double_format = 0xa4e6f0, long_double_bit = 96, long_double_format = 0xa4e710, ptr_bit = 32, addr_bit = 32, char_signed = 1, read_pc = 0, write_pc = 0x4758b0 <i386_linux_write_pc>, virtual_frame_pointer = 0x5418a0 <legacy_virtual_frame_pointer>, pseudo_register_read = 0x46c1d0 <i386_pseudo_register_read>, pseudo_register_write = 0x46c110 <i386_pseudo_register_write>, num_regs = 42, num_pseudo_regs = 8, sp_regnum = 4, pc_regnum = 8, ps_regnum = 9, fp0_regnum = 16, stab_reg_to_regnum = 0x46aef0 <i386_svr4_reg_to_regnum>, ecoff_reg_to_regnum = 0x540a60 <no_op_reg_to_regnum>, sdb_reg_to_regnum = 0x46ae40 <i386_dbx_reg_to_regnum>, dwarf2_reg_to_regnum = 0x46aef0 <i386_svr4_reg_to_regnum>, register_name = 0x5c46f0 <tdesc_register_name>, register_type = 0x5c4df0 <tdesc_register_type>, dummy_id = 0x46b810 <i386_dummy_id>, deprecated_fp_regnum = -1, push_dummy_call = 0x46c6f0 <i386_push_dummy_call>, call_dummy_location = 4, push_dummy_code = 0, ---Type <return> to continue, or q <return> to quit---q print_registers_info = 0x51dcb0 <default_print_registers_Quit (top-gdb) p *target_gdbarch->bfd_arch_info $3 = {bits_per_word = 32, bits_per_address = 32, bits_per_byte = 8, arch = bfd_arch_i386, mach = 1, arch_name = 0x7b3bb2 "i386", printable_name = 0x7b3bb2 "i386", section_align_power = 3, the_default = 1, compatible = 0x609fa0 <bfd_default_compatible>, scan = 0x60a110 <bfd_default_scan>, next = 0x7bd100} (top-gdb) Gdb will load executable before calling amd64_linux_read_description At this point, target_gdbarch is set and knows inferior is 32bit or not. -- H.J. ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-22 14:17 ` H.J. Lu 2010-02-22 15:01 ` Mark Kettenis @ 2010-02-28 20:30 ` Mark Kettenis 2010-02-28 20:58 ` H.J. Lu 1 sibling, 1 reply; 39+ messages in thread From: Mark Kettenis @ 2010-02-28 20:30 UTC (permalink / raw) To: hjl.tools; +Cc: gdb-patches [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 3887 bytes --] > Date: Mon, 22 Feb 2010 06:17:29 -0800 > From: "H.J. Lu" <hjl.tools@gmail.com> > > >> +/* 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; > >> + > >> + switch (bfd_section_size (abfd, section)) > >> + { > >> + case 0x200: > >> + /* Linux/x86-64. */ > >> + return tdesc_amd64_linux; > >> + default: > >> + return NULL; > >> + } > >> +} > > > > This seems a bit odd to me. I'd expect this function to just return > > tdesc_amd64_linux unconditionally. > > The folowup patch for AVX will change it to > > xcr0 = i386_linux_core_read_xcr0 (gdbarch, target, abfd); > switch (bfd_section_size (abfd, section)) > { > case 0x200: > /* Linux/x86-64. */ > if ((xcr0 & XSTATE_AVX_MASK) == XSTATE_AVX_MASK) > return tdesc_amd64_avx_linux; > else > return tdesc_amd64_linux; > default: > return NULL; > } > > Other OSes will need a similar change to support AVX. Even with that, checking the size of the .reg2 section makes no sense to me. > >> @@ -1282,10 +1292,31 @@ 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); > >> + > >> + /* Reserve a number for orig_rax. */ > >> 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); > > > > Why do you need to set num_regs here, but not the register_name, > > register_type and register_reggroup_p members? All four are set by > > tdesc_use_registers(). > > tdesc_use_registers is called after amd64_linux_init_abi. At this > point, num_regs is incorrect for Linux. We need to update it for > > valid_p = tdesc_numbered_register (feature, tdesc_data, > AMD64_LINUX_ORIG_RAX_REGNUM, > "orig_rax"); Sorry, but I don't understand this. How does checking a register in the target description care about the number of registers set in the gdbarch we're building? > >> + > >> + if (! tdesc_has_registers (tdesc)) > >> + tdesc = tdesc_amd64_linux; > >> + tdep->tdesc = tdesc; > >> + > >> + feature = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.linux"); > > > > Shouldn't that be org.gnu.gdb.amd64.linux? > > 64bit-core.xml and 64bit-sse.xml have > > <feature name="org.gnu.gdb.i386.core"> > > and > > <feature name="org.gnu.gdb.i386.sse"> Which seems wrong to me. Both the core registers and the SSE registers are different in 64-bit mode. But perhaps Daniel can shed some light on how these features are supposed to be used? > so that i386_gdbarch_init can have > > /* 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"); > > after > > /* Hook in ABI-specific overrides, if they have been registered. */ > info.tdep_info = (void *) tdesc_data; > gdbarch_init_osabi (info, gdbarch); > > It will be odd for 64bit-linux.xml to have > > <feature name="org.gnu.gdb.i386.linux"> Exactly. So why is it ok for 64bit-sse.xml to have <fearure name="org.gnu.gdb.i386.sse"> ? ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-28 20:30 ` Mark Kettenis @ 2010-02-28 20:58 ` H.J. Lu 2010-02-28 22:23 ` Daniel Jacobowitz 0 siblings, 1 reply; 39+ messages in thread From: H.J. Lu @ 2010-02-28 20:58 UTC (permalink / raw) To: Mark Kettenis, Daniel Jacobowitz; +Cc: gdb-patches On Sun, Feb 28, 2010 at 12:30 PM, Mark Kettenis <mark.kettenis@xs4all.nl> wrote: >> Date: Mon, 22 Feb 2010 06:17:29 -0800 >> From: "H.J. Lu" <hjl.tools@gmail.com> >> >> >> +/* 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; >> >> + >> >> + áswitch (bfd_section_size (abfd, section)) >> >> + á á{ >> >> + á ácase 0x200: >> >> + á á á/* Linux/x86-64. á*/ >> >> + á á áreturn tdesc_amd64_linux; >> >> + á ádefault: >> >> + á á áreturn NULL; >> >> + á á} >> >> +} >> > >> > This seems a bit odd to me. áI'd expect this function to just return >> > tdesc_amd64_linux unconditionally. >> >> The folowup patch for AVX will change it to >> >> xcr0 = i386_linux_core_read_xcr0 (gdbarch, target, abfd); >> switch (bfd_section_size (abfd, section)) >> { >> case 0x200: >> /* Linux/x86-64. */ >> if ((xcr0 & XSTATE_AVX_MASK) == XSTATE_AVX_MASK) >> return tdesc_amd64_avx_linux; >> else >> return tdesc_amd64_linux; >> default: >> return NULL; >> } >> >> Other OSes will need a similar change to support AVX. > > Even with that, checking the size of the .reg2 section makes no sense > to me. It is sanity check for corrupted core dump. I will remove it since you think it isn't needed. >> >> @@ -1282,10 +1292,31 @@ 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); >> >> + >> >> + á/* Reserve a number for orig_rax. á*/ >> >> á á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); >> > >> > Why do you need to set num_regs here, but not the register_name, >> > register_type and register_reggroup_p members? áAll four are set by >> > tdesc_use_registers(). >> >> tdesc_use_registers is called after amd64_linux_init_abi. At this >> point, num_regs is incorrect for Linux. We need to update it for >> >> valid_p = tdesc_numbered_register (feature, tdesc_data, >> AMD64_LINUX_ORIG_RAX_REGNUM, >> "orig_rax"); > > Sorry, but I don't understand this. How does checking a register in > the target description care about the number of registers set in the > gdbarch we're building? I copied it from ppc_linux_init_abi. Gdb won't work if I don't reserve a register number for orig_rax: (gdb) r /bin/ls Starting program: /export/build/gnu/gdb-xstate/build-x86_64-linux/gdb/gdb /bin/ls [Thread debugging using libthread_db enabled] Detaching after fork from child process 7791. GNU gdb (GDB) 7.1.50.20100228-cvs Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-unknown-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... /export/gnu/import/git/gdb-xstate/gdb/target-descriptions.c:1098: internal-error: tdesc_use_registers: Assertion `VEC_length (tdesc_arch_reg, data->arch_regs) <= num_regs' failed. Maybe Daniel knows the answer. >> >> + >> >> + áif (! tdesc_has_registers (tdesc)) >> >> + á átdesc = tdesc_amd64_linux; >> >> + átdep->tdesc = tdesc; >> >> + >> >> + áfeature = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.linux"); >> > >> > Shouldn't that be org.gnu.gdb.amd64.linux? >> >> 64bit-core.xml and 64bit-sse.xml have >> >> <feature name="org.gnu.gdb.i386.core"> >> >> and >> >> <feature name="org.gnu.gdb.i386.sse"> > > Which seems wrong to me. Both the core registers and the SSE > registers are different in 64-bit mode. But perhaps Daniel can shed > some light on how these features are supposed to be used? > >> so that i386_gdbarch_init can have >> >> /* 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"); >> >> after >> >> /* Hook in ABI-specific overrides, if they have been registered. */ >> info.tdep_info = (void *) tdesc_data; >> gdbarch_init_osabi (info, gdbarch); >> >> It will be odd for 64bit-linux.xml to have >> >> <feature name="org.gnu.gdb.i386.linux"> > > Exactly. So why is it ok for 64bit-sse.xml to have > > <fearure name="org.gnu.gdb.i386.sse"> > > ? > The reason is i386_validate_tdesc_p is called by i386_gdbarch_init after calling gdbarch_init_osabi, which may set up a 64bit target description. If 64bit target description has different feature name, it won't find core and SSE registers. If you don't like "i386" in the feature name, I can change it to x86. FWIW, BFD uses bfd_arch_i386 for both i386 and amd64. I think that is where i386 comes from. -- H.J. ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-28 20:58 ` H.J. Lu @ 2010-02-28 22:23 ` Daniel Jacobowitz 0 siblings, 0 replies; 39+ messages in thread From: Daniel Jacobowitz @ 2010-02-28 22:23 UTC (permalink / raw) To: H.J. Lu; +Cc: Mark Kettenis, gdb-patches On Sun, Feb 28, 2010 at 12:58:40PM -0800, H.J. Lu wrote: > > Sorry, but I don't understand this. Â How does checking a register in > > the target description care about the number of registers set in the > > gdbarch we're building? > > I copied it from ppc_linux_init_abi. Gdb won't work if I don't reserve > a register number for orig_rax: This part of the target descriptions infrastructure was designed to clean up a confusing aspect of some backends. If there are well-known registers - things that GDB has to treat specially for calling conventions, or read from to determine mode, anything like that - this lets us give them a fixed register number with a #define. Then, the register is concealed at runtime if it is not present on the target. If you want to have an orig_rax register with a constant register number, you need to bump up num_regs above that constant. So the key here is that he's not checking a register in the target. Independent of the target description supplied, he's bumping up the total "number of registers" to leave a gap for AMD64_LINUX_ORIG_RAX_REGNUM, because we said that AMD64_LINUX_ORIG_RAX_REGNUM was a valid register number (via the tdesc_numbered_register call). Is that clearer? > > Which seems wrong to me. Â Both the core registers and the SSE > > registers are different in 64-bit mode. Â But perhaps Daniel can shed > > some light on how these features are supposed to be used? There are two ways to do this. For Power, as HJ has pointed out, the features have size-independent names because they are mostly the same. There's still an r0, it's just 64-bit instead of 32-bit. Alternatively, you can define a 32-bit feature and a 64-bit feature with different names. IMO it does not make a lot of difference which version you choose. I would have chosen to give them separate names; there are too many differences, and I think it would simplify the code. But given how amd64 support is treated as an extension of GDB's i386 support, I can imagine that this approach makes sense. If we do stick to a single version, the x86 name seems better than i386. > The reason is i386_validate_tdesc_p is called by > i386_gdbarch_init after calling gdbarch_init_osabi, > which may set up a 64bit target description. If 64bit > target description has different feature name, it won't > find core and SSE registers. If you don't like "i386" > in the feature name, I can change it to x86. That's not a reason. You could just as easily make the code handle both variants. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-22 13:42 ` Mark Kettenis 2010-02-22 14:17 ` H.J. Lu @ 2010-02-22 14:41 ` Daniel Jacobowitz 2010-02-22 15:34 ` H.J. Lu 1 sibling, 1 reply; 39+ messages in thread From: Daniel Jacobowitz @ 2010-02-22 14:41 UTC (permalink / raw) To: Mark Kettenis; +Cc: hjl.tools, gdb-patches On Mon, Feb 22, 2010 at 02:42:28PM +0100, Mark Kettenis wrote: > > +/* Get Linux/x86 target description from running target. */ > > + > > +static const struct target_desc * > > +amd64_linux_read_description (struct target_ops *ops) > > +{ > > + if (gdbarch_ptr_bit (target_gdbarch) == 64) > > + return tdesc_amd64_linux; > > + else > > + return tdesc_i386_linux; > > +} > > + > > This made me wonder what happens if you attach to a process without > loading an executable first. Currently this works, since GDB can > figure out what executable belongs to the the process and load the > executable automatically. But I fear a chicken & egg problem here: > the gdbarch is derviced from the tdesc, but in order to determine the > tdesc you need a gdbarch. Yes, I'm not comfortable having this function respond based on the gdbarch. It's supposed to query the target. For instance, if you had a ptrace request that failed if the target was 32-bit, you could use that. If that's not possible, it probably shouldn't be implemented. > I didn't realize these functions would effectively be moved into > target-descriptions.c. That feels wrong. For avoidance of doubt, that's true of the flags functions and the builtin FP type; the vector type goes into the data files. The FP type there's no real way around. The flags types could (I think should) be transfered to the data files too - but it would require a new element in the XML files. I happen to have that patch sitting around somewhere... let me find it. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-22 14:41 ` Daniel Jacobowitz @ 2010-02-22 15:34 ` H.J. Lu 2010-02-22 15:52 ` Daniel Jacobowitz 0 siblings, 1 reply; 39+ messages in thread From: H.J. Lu @ 2010-02-22 15:34 UTC (permalink / raw) To: Mark Kettenis, hjl.tools, gdb-patches On Mon, Feb 22, 2010 at 6:41 AM, Daniel Jacobowitz <dan@codesourcery.com> wrote: > On Mon, Feb 22, 2010 at 02:42:28PM +0100, Mark Kettenis wrote: >> > +/* Get Linux/x86 target description from running target. */ >> > + >> > +static const struct target_desc * >> > +amd64_linux_read_description (struct target_ops *ops) >> > +{ >> > + if (gdbarch_ptr_bit (target_gdbarch) == 64) >> > + return tdesc_amd64_linux; >> > + else >> > + return tdesc_i386_linux; >> > +} >> > + >> >> This made me wonder what happens if you attach to a process without >> loading an executable first. Currently this works, since GDB can >> figure out what executable belongs to the the process and load the >> executable automatically. But I fear a chicken & egg problem here: >> the gdbarch is derviced from the tdesc, but in order to determine the >> tdesc you need a gdbarch. > > Yes, I'm not comfortable having this function respond based on the > gdbarch. It's supposed to query the target. For instance, if you had > a ptrace request that failed if the target was 32-bit, you could use > that. If that's not possible, it probably shouldn't be implemented. > I just need to know if the inferior is 32bit or 64bit. Why shouldn't target_gdbarch be used? At this point, target_gdbarch should have the correct bfd cpu info. Is that correct? -- H.J. ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-22 15:34 ` H.J. Lu @ 2010-02-22 15:52 ` Daniel Jacobowitz 2010-02-22 15:58 ` H.J. Lu 0 siblings, 1 reply; 39+ messages in thread From: Daniel Jacobowitz @ 2010-02-22 15:52 UTC (permalink / raw) To: H.J. Lu; +Cc: Mark Kettenis, gdb-patches On Mon, Feb 22, 2010 at 07:34:01AM -0800, H.J. Lu wrote: > I just need to know if the inferior is 32bit or 64bit. Why shouldn't > target_gdbarch be used? At this point, target_gdbarch should have > the correct bfd cpu info. Is that correct? Not if, for instance, we did not find the executable. If you are just guessing based on the gdbarch, what value does this function add? -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-22 15:52 ` Daniel Jacobowitz @ 2010-02-22 15:58 ` H.J. Lu 2010-02-22 16:10 ` Daniel Jacobowitz 0 siblings, 1 reply; 39+ messages in thread From: H.J. Lu @ 2010-02-22 15:58 UTC (permalink / raw) To: H.J. Lu, Mark Kettenis, gdb-patches On Mon, Feb 22, 2010 at 7:52 AM, Daniel Jacobowitz <dan@codesourcery.com> wrote: > On Mon, Feb 22, 2010 at 07:34:01AM -0800, H.J. Lu wrote: >> I just need to know if the inferior is 32bit or 64bit. Why shouldn't >> target_gdbarch be used? At this point, target_gdbarch should have >> the correct bfd cpu info. Is that correct? > > Not if, for instance, we did not find the executable. How do you debug if you can't find executable? I am not sure if you can get that far. > If you are just guessing based on the gdbarch, what value does this > function add? > AVX version is static const struct target_desc * amd64_linux_read_description (struct target_ops *ops) { gdb_assert (i386_xstate.status != XSTATE_UNKNOWN); if (have_ptrace_getregset == -1) { int tid; unsigned long long xstateregs[i386_xstate.n_of_int64]; struct iovec iov; /* GNU/Linux LWP ID's are process ID's. */ tid = TIDGET (inferior_ptid); if (tid == 0) tid = PIDGET (inferior_ptid); /* Not a threaded program. */ iov.iov_base = xstateregs; iov.iov_len = i386_xstate.size; /* Check if PTRACE_GETREGSET works. */ if (ptrace (PTRACE_GETREGSET, tid, (unsigned int) NT_X86_XSTATE, (long) &iov) < 0) have_ptrace_getregset = 0; else have_ptrace_getregset = 1; } /* Check the native XCR0 only if PTRACE_GETREGSET is available. */ if (have_ptrace_getregset && (i386_xstate.xcr0 & XSTATE_AVX_MASK) == XSTATE_AVX_MASK) { if (gdbarch_ptr_bit (target_gdbarch) == 64) return tdesc_amd64_avx_linux; else return tdesc_i386_avx_linux; } else { if (gdbarch_ptr_bit (target_gdbarch) == 64) return tdesc_amd64_linux; else return tdesc_i386_linux; } } That is we use AVX target only if kernel and hardware support it. -- H.J. ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-22 15:58 ` H.J. Lu @ 2010-02-22 16:10 ` Daniel Jacobowitz 2010-02-22 16:58 ` Mark Kettenis 0 siblings, 1 reply; 39+ messages in thread From: Daniel Jacobowitz @ 2010-02-22 16:10 UTC (permalink / raw) To: H.J. Lu; +Cc: Mark Kettenis, gdb-patches On Mon, Feb 22, 2010 at 07:57:52AM -0800, H.J. Lu wrote: > On Mon, Feb 22, 2010 at 7:52 AM, Daniel Jacobowitz <dan@codesourcery.com> wrote: > > On Mon, Feb 22, 2010 at 07:34:01AM -0800, H.J. Lu wrote: > >> I just need to know if the inferior is 32bit or 64bit. Why shouldn't > >> target_gdbarch be used? At this point, target_gdbarch should have > >> the correct bfd cpu info. Is that correct? > > > > Not if, for instance, we did not find the executable. > > How do you debug if you can't find executable? I am not sure if > you can get that far. That's not the point. You can not rely on the gdbarch here. It breaks the entire abstraction to circularly read the architecture description from the architecture. Plus it will do the wrong thing if the user gives the wrong executable, and this is our chance to get it right. Why can't you figure this out with ptrace? Isn't there a bit in flags, or something like that? Or a way to get at the kernel's TIF_IA32 flag? -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-22 16:10 ` Daniel Jacobowitz @ 2010-02-22 16:58 ` Mark Kettenis 2010-02-22 17:03 ` Daniel Jacobowitz 0 siblings, 1 reply; 39+ messages in thread From: Mark Kettenis @ 2010-02-22 16:58 UTC (permalink / raw) To: dan; +Cc: hjl.tools, gdb-patches > Date: Mon, 22 Feb 2010 11:10:40 -0500 > From: Daniel Jacobowitz <dan@codesourcery.com> > > On Mon, Feb 22, 2010 at 07:57:52AM -0800, H.J. Lu wrote: > > On Mon, Feb 22, 2010 at 7:52 AM, Daniel Jacobowitz <dan@codesourcery.com> wrote: > > > On Mon, Feb 22, 2010 at 07:34:01AM -0800, H.J. Lu wrote: > > >> I just need to know if the inferior is 32bit or 64bit. Why shouldn't > > >> target_gdbarch be used? At this point, target_gdbarch should have > > >> the correct bfd cpu info. Is that correct? > > > > > > Not if, for instance, we did not find the executable. > > > > How do you debug if you can't find executable? I am not sure if > > you can get that far. > > That's not the point. You can not rely on the gdbarch here. It > breaks the entire abstraction to circularly read the architecture > description from the architecture. Plus it will do the wrong thing if > the user gives the wrong executable, and this is our chance to get it > right. > > Why can't you figure this out with ptrace? Isn't there a bit in > flags, or something like that? Or a way to get at the kernel's > TIF_IA32 flag? I've looked at the Linux kernel sources for the kernel on my workstation (2.6.27 in its OpenSUSE incarnation), and the only way to distinguish between a 32-bit and a 64-bit process seems to be to attempt to write one of the debug address registers with a value that's larger than 0xffffffff. If that fails, you have a 32-bit process, otherwise it's a 64-bit process. ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-22 16:58 ` Mark Kettenis @ 2010-02-22 17:03 ` Daniel Jacobowitz 2010-02-22 19:52 ` Mark Kettenis 0 siblings, 1 reply; 39+ messages in thread From: Daniel Jacobowitz @ 2010-02-22 17:03 UTC (permalink / raw) To: Mark Kettenis; +Cc: hjl.tools, gdb-patches On Mon, Feb 22, 2010 at 05:56:58PM +0100, Mark Kettenis wrote: > I've looked at the Linux kernel sources for the kernel on my > workstation (2.6.27 in its OpenSUSE incarnation), and the only way to > distinguish between a 32-bit and a 64-bit process seems to be to > attempt to write one of the debug address registers with a value > that's larger than 0xffffffff. If that fails, you have a 32-bit > process, otherwise it's a 64-bit process. Yuck :-( But I didn't see anything else either. Is there an eflags bit for this? Even if so, IIRC, we may not want to use it; it's possible to run 32-bit code in a 64-bit process and some overly clever programs may do so. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-22 17:03 ` Daniel Jacobowitz @ 2010-02-22 19:52 ` Mark Kettenis 2010-02-22 21:06 ` H.J. Lu 0 siblings, 1 reply; 39+ messages in thread From: Mark Kettenis @ 2010-02-22 19:52 UTC (permalink / raw) To: dan; +Cc: hjl.tools, gdb-patches > Date: Mon, 22 Feb 2010 12:03:03 -0500 > From: Daniel Jacobowitz <dan@codesourcery.com> > > On Mon, Feb 22, 2010 at 05:56:58PM +0100, Mark Kettenis wrote: > > I've looked at the Linux kernel sources for the kernel on my > > workstation (2.6.27 in its OpenSUSE incarnation), and the only way to > > distinguish between a 32-bit and a 64-bit process seems to be to > > attempt to write one of the debug address registers with a value > > that's larger than 0xffffffff. If that fails, you have a 32-bit > > process, otherwise it's a 64-bit process. > > Yuck :-( But I didn't see anything else either. Indeed. > Is there an eflags bit for this? Even if so, IIRC, we may not want to > use it; it's possible to run 32-bit code in a 64-bit process and some > overly clever programs may do so. Nope, there is no %eflags/%rflags bit for this. Not quite sure what running 32-bit code in a 64-bit process actually means. But I'd guess you want the 64-bit view on the registers in that case. Anyway, I think it's probably best if HJ leaves this bit out of this diff for now. We can revisit the issue when AVX support is introduced. ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-22 19:52 ` Mark Kettenis @ 2010-02-22 21:06 ` H.J. Lu 2010-02-22 21:31 ` Mark Kettenis 0 siblings, 1 reply; 39+ messages in thread From: H.J. Lu @ 2010-02-22 21:06 UTC (permalink / raw) To: Mark Kettenis; +Cc: dan, gdb-patches On Mon, Feb 22, 2010 at 11:50 AM, Mark Kettenis <mark.kettenis@xs4all.nl> wrote: >> Date: Mon, 22 Feb 2010 12:03:03 -0500 >> From: Daniel Jacobowitz <dan@codesourcery.com> >> >> On Mon, Feb 22, 2010 at 05:56:58PM +0100, Mark Kettenis wrote: >> > I've looked at the Linux kernel sources for the kernel on my >> > workstation (2.6.27 in its OpenSUSE incarnation), and the only way to >> > distinguish between a 32-bit and a 64-bit process seems to be to >> > attempt to write one of the debug address registers with a value >> > that's larger than 0xffffffff. If that fails, you have a 32-bit >> > process, otherwise it's a 64-bit process. >> >> Yuck :-( But I didn't see anything else either. > > Indeed. > >> Is there an eflags bit for this? Even if so, IIRC, we may not want to >> use it; it's possible to run 32-bit code in a 64-bit process and some >> overly clever programs may do so. > > Nope, there is no %eflags/%rflags bit for this. Not quite sure what > running 32-bit code in a 64-bit process actually means. But I'd guess > you want the 64-bit view on the registers in that case. > > Anyway, I think it's probably best if HJ leaves this bit out of this > diff for now. We can revisit the issue when AVX support is > introduced. > Please see if my latest patch is OK: --- /* 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")); /* Value of CS register: 1. 64bit: 0x33. 2. 32bit: 0x23. */ if (cs == 0x33) return tdesc_amd64_linux; else return tdesc_i386_linux; --- In kernel, there is regs->cs = test_thread_flag(TIF_64BIT_ILP32) ? __USER_CS : __USER32_CS; Thanks. -- H.J. ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-22 21:06 ` H.J. Lu @ 2010-02-22 21:31 ` Mark Kettenis 2010-02-22 21:41 ` H.J. Lu 0 siblings, 1 reply; 39+ messages in thread From: Mark Kettenis @ 2010-02-22 21:31 UTC (permalink / raw) To: hjl.tools; +Cc: dan, gdb-patches [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 2074 bytes --] > Date: Mon, 22 Feb 2010 13:06:31 -0800 > From: "H.J. Lu" <hjl.tools@gmail.com> > > On Mon, Feb 22, 2010 at 11:50 AM, Mark Kettenis <mark.kettenis@xs4all.nl> wrote: > >> Date: Mon, 22 Feb 2010 12:03:03 -0500 > >> From: Daniel Jacobowitz <dan@codesourcery.com> > >> > >> On Mon, Feb 22, 2010 at 05:56:58PM +0100, Mark Kettenis wrote: > >> > I've looked at the Linux kernel sources for the kernel on my > >> > workstation (2.6.27 in its OpenSUSE incarnation), and the only way to > >> > distinguish between a 32-bit and a 64-bit process seems to be to > >> > attempt to write one of the debug address registers with a value > >> > that's larger than 0xffffffff. If that fails, you have a 32-bit > >> > process, otherwise it's a 64-bit process. > >> > >> Yuck :-( But I didn't see anything else either. > > > > Indeed. > > > >> Is there an eflags bit for this? Even if so, IIRC, we may not want to > >> use it; it's possible to run 32-bit code in a 64-bit process and some > >> overly clever programs may do so. > > > > Nope, there is no %eflags/%rflags bit for this. Not quite sure what > > running 32-bit code in a 64-bit process actually means. But I'd guess > > you want the 64-bit view on the registers in that case. > > > > Anyway, I think it's probably best if HJ leaves this bit out of this > > diff for now. We can revisit the issue when AVX support is > > introduced. > > > > Please see if my latest patch is OK: > > --- > /* 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")); > > /* Value of CS register: > 1. 64bit: 0x33. > 2. 32bit: 0x23. > */ > if (cs == 0x33) > return tdesc_amd64_linux; > else > return tdesc_i386_linux; > --- > > In kernel, there is > > regs->cs = test_thread_flag(TIF_64BIT_ILP32) ? __USER_CS : __USER32_CS; I fear that's rather fragile. I mean, the actual value of __USER_CS/__USER32_CS is just an implementation detail isn't it? ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-22 21:31 ` Mark Kettenis @ 2010-02-22 21:41 ` H.J. Lu 2010-02-22 22:05 ` H. Peter Anvin 2010-02-28 20:12 ` Mark Kettenis 0 siblings, 2 replies; 39+ messages in thread From: H.J. Lu @ 2010-02-22 21:41 UTC (permalink / raw) To: Mark Kettenis; +Cc: dan, gdb-patches, Suresh Siddha, H. Peter Anvin On Mon, Feb 22, 2010 at 1:30 PM, Mark Kettenis <mark.kettenis@xs4all.nl> wrote: >> Date: Mon, 22 Feb 2010 13:06:31 -0800 >> From: "H.J. Lu" <hjl.tools@gmail.com> >> >> On Mon, Feb 22, 2010 at 11:50 AM, Mark Kettenis <mark.kettenis@xs4all.nl> wrote: >> >> Date: Mon, 22 Feb 2010 12:03:03 -0500 >> >> From: Daniel Jacobowitz <dan@codesourcery.com> >> >> >> >> On Mon, Feb 22, 2010 at 05:56:58PM +0100, Mark Kettenis wrote: >> >> > I've looked at the Linux kernel sources for the kernel on my >> >> > workstation (2.6.27 in its OpenSUSE incarnation), and the only way to >> >> > distinguish between a 32-bit and a 64-bit process seems to be to >> >> > attempt to write one of the debug address registers with a value >> >> > that's larger than 0xffffffff. If that fails, you have a 32-bit >> >> > process, otherwise it's a 64-bit process. >> >> >> >> Yuck :-( But I didn't see anything else either. >> > >> > Indeed. >> > >> >> Is there an eflags bit for this? Even if so, IIRC, we may not want to >> >> use it; it's possible to run 32-bit code in a 64-bit process and some >> >> overly clever programs may do so. >> > >> > Nope, there is no %eflags/%rflags bit for this. Not quite sure what >> > running 32-bit code in a 64-bit process actually means. But I'd guess >> > you want the 64-bit view on the registers in that case. >> > >> > Anyway, I think it's probably best if HJ leaves this bit out of this >> > diff for now. We can revisit the issue when AVX support is >> > introduced. >> > >> >> Please see if my latest patch is OK: >> >> --- >> /* 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")); >> >> /* Value of CS register: >> 1. 64bit: 0x33. >> 2. 32bit: 0x23. >> */ >> if (cs == 0x33) >> return tdesc_amd64_linux; >> else >> return tdesc_i386_linux; >> --- >> >> In kernel, there is >> >> regs->cs = test_thread_flag(TIF_64BIT_ILP32) ? __USER_CS : __USER32_CS; > > I fear that's rather fragile. I mean, the actual value of > __USER_CS/__USER32_CS is just an implementation detail isn't it? > That is how strace checks 32bit process on Linux/x86-64 I have discussed it with Peter and Suresh. It is very unlikely Linux kernel will break strace. In any case, we will add a new ptrace option to Linux 2.6.35 to get TIF_64BIT_ILP32 among other things. I will update gdb to try the new ptrace option first and then fail back to CS register. Thanks. -- H.J. ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-22 21:41 ` H.J. Lu @ 2010-02-22 22:05 ` H. Peter Anvin 2010-02-22 22:07 ` H.J. Lu 2010-02-28 20:12 ` Mark Kettenis 1 sibling, 1 reply; 39+ messages in thread From: H. Peter Anvin @ 2010-02-22 22:05 UTC (permalink / raw) To: H.J. Lu; +Cc: Mark Kettenis, dan, gdb-patches, Suresh Siddha On 02/22/2010 01:41 PM, H.J. Lu wrote: >>> >>> Please see if my latest patch is OK: >>> >>> --- >>> /* 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")); >>> >>> /* Value of CS register: >>> 1. 64bit: 0x33. >>> 2. 32bit: 0x23. >>> */ >>> if (cs == 0x33) >>> return tdesc_amd64_linux; >>> else >>> return tdesc_i386_linux; >>> --- >>> >>> In kernel, there is >>> >>> regs->cs = test_thread_flag(TIF_64BIT_ILP32) ? __USER_CS : __USER32_CS; >> >> I fear that's rather fragile. I mean, the actual value of >> __USER_CS/__USER32_CS is just an implementation detail isn't it? >> > > That is how strace checks 32bit process on Linux/x86-64 I have > discussed it with Peter and Suresh. It is very unlikely Linux kernel will > break strace. In any case, we will add a new ptrace option to Linux > 2.6.35 to get TIF_64BIT_ILP32 among other things. I will update gdb > to try the new ptrace option first and then fail back to CS register. > Uhm... TIF_64BIT_ILP32 didn't go upstream (remember, we shut down that project?) What I suggested was to add an strace option to get the segment descriptor flags, which would include the CS.L bit for 64-bit mode. -hpa ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-22 22:05 ` H. Peter Anvin @ 2010-02-22 22:07 ` H.J. Lu 2010-02-22 22:15 ` H. Peter Anvin 0 siblings, 1 reply; 39+ messages in thread From: H.J. Lu @ 2010-02-22 22:07 UTC (permalink / raw) To: H. Peter Anvin; +Cc: Mark Kettenis, dan, gdb-patches, Suresh Siddha On Mon, Feb 22, 2010 at 2:02 PM, H. Peter Anvin <hpa@zytor.com> wrote: > On 02/22/2010 01:41 PM, H.J. Lu wrote: >>>> >>>> Please see if my latest patch is OK: >>>> >>>> --- >>>> /* 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")); >>>> >>>> /* Value of CS register: >>>> 1. 64bit: 0x33. >>>> 2. 32bit: 0x23. >>>> */ >>>> if (cs == 0x33) >>>> return tdesc_amd64_linux; >>>> else >>>> return tdesc_i386_linux; >>>> --- >>>> >>>> In kernel, there is >>>> >>>> regs->cs = test_thread_flag(TIF_64BIT_ILP32) ? __USER_CS : __USER32_CS; >>> >>> I fear that's rather fragile. I mean, the actual value of >>> __USER_CS/__USER32_CS is just an implementation detail isn't it? >>> >> >> That is how strace checks 32bit process on Linux/x86-64 I have >> discussed it with Peter and Suresh. It is very unlikely Linux kernel will >> break strace. In any case, we will add a new ptrace option to Linux >> 2.6.35 to get TIF_64BIT_ILP32 among other things. I will update gdb >> to try the new ptrace option first and then fail back to CS register. >> > > Uhm... TIF_64BIT_ILP32 didn't go upstream (remember, we shut down that > project?) > > What I suggested was to add an strace option to get the segment > descriptor flags, which would include the CS.L bit for 64-bit mode. > Oops. Wrong kernel source. The idea is the same. It is the CS.L bit for 64-bit mode. That is /* Value of CS register: 1. 64bit: 0x33. 2. 32bit: 0x23. */ -- H.J. ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-22 22:07 ` H.J. Lu @ 2010-02-22 22:15 ` H. Peter Anvin 2010-02-22 22:21 ` H.J. Lu 0 siblings, 1 reply; 39+ messages in thread From: H. Peter Anvin @ 2010-02-22 22:15 UTC (permalink / raw) To: H.J. Lu; +Cc: Mark Kettenis, dan, gdb-patches, Suresh Siddha On 02/22/2010 02:07 PM, H.J. Lu wrote: > > Oops. Wrong kernel source. The idea is the same. It is the CS.L bit > for 64-bit mode. That is > > /* Value of CS register: > 1. 64bit: 0x33. > 2. 32bit: 0x23. > */ > That's not the CS.L bit; that's the selector value (which is currently the only thing exported.) The future extension should export the descriptor information instead of relying on fixed values. -hpa ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-22 22:15 ` H. Peter Anvin @ 2010-02-22 22:21 ` H.J. Lu 0 siblings, 0 replies; 39+ messages in thread From: H.J. Lu @ 2010-02-22 22:21 UTC (permalink / raw) To: H. Peter Anvin; +Cc: Mark Kettenis, dan, gdb-patches, Suresh Siddha On Mon, Feb 22, 2010 at 2:13 PM, H. Peter Anvin <hpa@zytor.com> wrote: > On 02/22/2010 02:07 PM, H.J. Lu wrote: >> >> Oops. Wrong kernel source. The idea is the same. It is the CS.L bit >> for 64-bit mode. That is >> >> /* Value of CS register: >> 1. 64bit: 0x33. >> 2. 32bit: 0x23. >> */ >> > > That's not the CS.L bit; that's the selector value (which is currently > the only thing exported.) The future extension should export the > descriptor information instead of relying on fixed values. > Yes, for the time being, gdb checks CS value before the new ptrace option is added to kernel. After that, gdb will be changed to check the the CS.L bit first and fail back to CS value. -- H.J. ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-22 21:41 ` H.J. Lu 2010-02-22 22:05 ` H. Peter Anvin @ 2010-02-28 20:12 ` Mark Kettenis 1 sibling, 0 replies; 39+ messages in thread From: Mark Kettenis @ 2010-02-28 20:12 UTC (permalink / raw) To: hjl.tools; +Cc: dan, gdb-patches, suresh.b.siddha, hpa [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 2934 bytes --] > Date: Mon, 22 Feb 2010 13:41:07 -0800 > From: "H.J. Lu" <hjl.tools@gmail.com> > > On Mon, Feb 22, 2010 at 1:30 PM, Mark Kettenis <mark.kettenis@xs4all.nl> wrote: > >> Date: Mon, 22 Feb 2010 13:06:31 -0800 > >> From: "H.J. Lu" <hjl.tools@gmail.com> > >> > >> On Mon, Feb 22, 2010 at 11:50 AM, Mark Kettenis <mark.kettenis@xs4all.nl> wrote: > >> >> Date: Mon, 22 Feb 2010 12:03:03 -0500 > >> >> From: Daniel Jacobowitz <dan@codesourcery.com> > >> >> > >> >> On Mon, Feb 22, 2010 at 05:56:58PM +0100, Mark Kettenis wrote: > >> >> > I've looked at the Linux kernel sources for the kernel on my > >> >> > workstation (2.6.27 in its OpenSUSE incarnation), and the only way to > >> >> > distinguish between a 32-bit and a 64-bit process seems to be to > >> >> > attempt to write one of the debug address registers with a value > >> >> > that's larger than 0xffffffff. If that fails, you have a 32-bit > >> >> > process, otherwise it's a 64-bit process. > >> >> > >> >> Yuck :-( But I didn't see anything else either. > >> > > >> > Indeed. > >> > > >> >> Is there an eflags bit for this? Even if so, IIRC, we may not want to > >> >> use it; it's possible to run 32-bit code in a 64-bit process and some > >> >> overly clever programs may do so. > >> > > >> > Nope, there is no %eflags/%rflags bit for this. Not quite sure what > >> > running 32-bit code in a 64-bit process actually means. But I'd guess > >> > you want the 64-bit view on the registers in that case. > >> > > >> > Anyway, I think it's probably best if HJ leaves this bit out of this > >> > diff for now. We can revisit the issue when AVX support is > >> > introduced. > >> > > >> > >> Please see if my latest patch is OK: > >> > >> --- > >> /* 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")); > >> > >> /* Value of CS register: > >> 1. 64bit: 0x33. > >> 2. 32bit: 0x23. > >> */ > >> if (cs == 0x33) > >> return tdesc_amd64_linux; > >> else > >> return tdesc_i386_linux; > >> --- > >> > >> In kernel, there is > >> > >> regs->cs = test_thread_flag(TIF_64BIT_ILP32) ? __USER_CS : __USER32_CS; > > > > I fear that's rather fragile. I mean, the actual value of > > __USER_CS/__USER32_CS is just an implementation detail isn't it? > > > > That is how strace checks 32bit process on Linux/x86-64 I have > discussed it with Peter and Suresh. It is very unlikely Linux kernel will > break strace. In any case, we will add a new ptrace option to Linux > 2.6.35 to get TIF_64BIT_ILP32 among other things. I will update gdb > to try the new ptrace option first and then fail back to CS register. OK, that makes it less fragile than I thought. But please use #defines with meaningful names instead of magic constants. ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-18 23:01 ` H.J. Lu 2010-02-22 13:42 ` Mark Kettenis @ 2010-02-22 21:04 ` H.J. Lu 2010-02-28 21:16 ` H.J. Lu 1 sibling, 1 reply; 39+ messages in thread From: H.J. Lu @ 2010-02-22 21:04 UTC (permalink / raw) To: H.J. Lu; +Cc: GDB 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? Thanks. H.J. --- gdb/ 2010-02-22 H.J. Lu <hongjiu.lu@intel.com> * amd64-linux-nat.c (amd64_linux_read_description): New. (_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-22 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-22 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..c4ed0b4 100644 --- a/gdb/amd64-linux-nat.c +++ b/gdb/amd64-linux-nat.c @@ -674,6 +674,36 @@ amd64_linux_siginfo_fixup (struct siginfo *native, gdb_byte *inf, int direction) return 0; } +/* Get Linux/x86 target description from running target. */ + +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")); + + /* Value of CS register: + 1. 64bit: 0x33. + 2. 32bit: 0x23. + */ + if (cs == 0x33) + return tdesc_amd64_linux; + else + return tdesc_i386_linux; +} + /* Provide a prototype to silence -Wmissing-prototypes. */ void _initialize_amd64_linux_nat (void); @@ -712,6 +742,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..95df2e6 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,38 @@ 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; + + switch (bfd_section_size (abfd, section)) + { + case 0x200: + /* Linux/x86-64. */ + return tdesc_amd64_linux; + default: + return NULL; + } +} + 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 +1281,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 +1309,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 +1324,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 +1520,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 (); +} \f /* 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..fbdc014 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,63 @@ 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; + + switch (bfd_section_size (abfd, section)) + { + case 0x6c: + /* Linux/i386. */ + return tdesc_i386_linux; + default: + return NULL; + } +} + 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 +815,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 +843,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, } \f -/* 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; +} + \f 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\"/>" } ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-22 21:04 ` H.J. Lu @ 2010-02-28 21:16 ` H.J. Lu 2010-03-01 14:49 ` Mark Kettenis 0 siblings, 1 reply; 39+ messages in thread From: H.J. Lu @ 2010-02-28 21:16 UTC (permalink / raw) To: H.J. Lu; +Cc: GDB 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? Thanks. H.J. ---- 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 (); +} \f /* 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, } \f -/* 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; +} + \f 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\"/>" } ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-02-28 21:16 ` H.J. Lu @ 2010-03-01 14:49 ` Mark Kettenis 2010-03-01 17:07 ` Daniel Jacobowitz 0 siblings, 1 reply; 39+ messages in thread From: Mark Kettenis @ 2010-03-01 14:49 UTC (permalink / raw) To: hjl.tools; +Cc: hjl.tools, gdb-patches > 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 (); > +} > \f > > /* 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, > } > \f > > -/* 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; > +} > + > \f > 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\"/>" > } > ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-03-01 14:49 ` Mark Kettenis @ 2010-03-01 17:07 ` Daniel Jacobowitz 2010-03-01 17:09 ` H.J. Lu 0 siblings, 1 reply; 39+ messages in thread From: Daniel Jacobowitz @ 2010-03-01 17:07 UTC (permalink / raw) To: Mark Kettenis; +Cc: hjl.tools, gdb-patches On Mon, Mar 01, 2010 at 03:48:55PM +0100, Mark Kettenis wrote: > Given Daniel's explanation about num_regs and the feature names, this > is ok with me. With me, too. Thanks for your patience, H. J. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 39+ messages in thread
* Re: PATCH: Enable x86 XML target descriptions 2010-03-01 17:07 ` Daniel Jacobowitz @ 2010-03-01 17:09 ` H.J. Lu 0 siblings, 0 replies; 39+ messages in thread From: H.J. Lu @ 2010-03-01 17:09 UTC (permalink / raw) To: Mark Kettenis, hjl.tools, gdb-patches On Mon, Mar 1, 2010 at 9:07 AM, Daniel Jacobowitz <dan@codesourcery.com> wrote: > On Mon, Mar 01, 2010 at 03:48:55PM +0100, Mark Kettenis wrote: >> Given Daniel's explanation about num_regs and the feature names, this >> is ok with me. > > With me, too. Thanks for your patience, H. J. > Thanks for Mark and Daniel's suggestions and comments. -- H.J. ^ permalink raw reply [flat|nested] 39+ messages in thread
end of thread, other threads:[~2010-03-01 17:09 UTC | newest] Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2010-02-10 20:03 PATCH: Enable x86 XML target descriptions H.J. Lu 2010-02-17 14:59 ` H.J. Lu 2010-02-17 15:23 ` Mark Kettenis 2010-02-17 15:42 ` H.J. Lu 2010-02-17 15:46 ` Daniel Jacobowitz 2010-02-17 16:19 ` Mark Kettenis 2010-02-18 5:44 ` H.J. Lu 2010-02-18 15:37 ` H.J. Lu 2010-02-18 23:01 ` H.J. Lu 2010-02-22 13:42 ` Mark Kettenis 2010-02-22 14:17 ` H.J. Lu 2010-02-22 15:01 ` Mark Kettenis 2010-02-22 15:27 ` H.J. Lu 2010-02-22 15:30 ` Daniel Jacobowitz 2010-02-22 15:39 ` H.J. Lu 2010-02-28 20:30 ` Mark Kettenis 2010-02-28 20:58 ` H.J. Lu 2010-02-28 22:23 ` Daniel Jacobowitz 2010-02-22 14:41 ` Daniel Jacobowitz 2010-02-22 15:34 ` H.J. Lu 2010-02-22 15:52 ` Daniel Jacobowitz 2010-02-22 15:58 ` H.J. Lu 2010-02-22 16:10 ` Daniel Jacobowitz 2010-02-22 16:58 ` Mark Kettenis 2010-02-22 17:03 ` Daniel Jacobowitz 2010-02-22 19:52 ` Mark Kettenis 2010-02-22 21:06 ` H.J. Lu 2010-02-22 21:31 ` Mark Kettenis 2010-02-22 21:41 ` H.J. Lu 2010-02-22 22:05 ` H. Peter Anvin 2010-02-22 22:07 ` H.J. Lu 2010-02-22 22:15 ` H. Peter Anvin 2010-02-22 22:21 ` H.J. Lu 2010-02-28 20:12 ` Mark Kettenis 2010-02-22 21:04 ` H.J. Lu 2010-02-28 21:16 ` H.J. Lu 2010-03-01 14:49 ` Mark Kettenis 2010-03-01 17:07 ` Daniel Jacobowitz 2010-03-01 17:09 ` H.J. Lu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox