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


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

[RFA] x86-64 segment registers handling


Hi all,
this patch synces gdb with recent ABI changes in x86-64 kernel, which 
added segment registers to user_regs_struct in corefile and ptrace() 
call. Because it was hard to find all places which could depend on this 
change I also did a cleanup. I joined most of registers information to 
one structure at the beginning of x86-64-tdep.c to make it more readable 
  and maintainable and changed some "anonymous constants" (numbers) to 
derivatives of #defines.
Can I commit?

Index: ChangeLog
	* x86-64-tdep.h (X86_64_NUM_REGS)
	(X86_64_NUM_GREGS): Delete #defines
	(x86_64_num_regs)
	(x86_64_num_gregs): Added extern variables.
	* x86-64-linux-nat.c (x86_64_regmap): Swapped
	RBX <> RDX, added DS, ES, FD, GS
	(x86_64_linux_dr_get_status), (supply_gregset),
	(fill_gregset): Changed X86_64_NUM_GREGS to
	x86_64_num_gregs
	* x86-64-tdep.c (x86_64_register_raw_size_table): Delete
	(x86_64_register_info_table): Add
	(X86_64_NUM_REGS, X86_64_NUM_GREGS): Add
	(x86_64_register_raw_size),
	(x86_64_register_virtual_type),
	(x86_64_register_name),
	(_initialize_x86_64_tdep): Changed to reflect new
	general x86_64_register_info_table.
	(i386_gdbarch_init): gdbarch_register_bytes is now set
	dynamicaly during initialization.

Michal Ludvig
-- 
* SuSE CR, s.r.o     * mludvig@suse.cz
* +420 2 9654 5373   * http://www.suse.cz
Index: x86-64-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/x86-64-tdep.c,v
retrieving revision 1.11
diff -c -3 -p -r1.11 x86-64-tdep.c
*** x86-64-tdep.c	2002/03/25 07:59:16	1.11
--- x86-64-tdep.c	2002/03/26 16:56:52
***************
*** 35,75 ****
  
  /* Register numbers of various important registers.  */
  #define RAX_REGNUM 0
! #define RDX_REGNUM 1
  #define RDI_REGNUM 5
  #define EFLAGS_REGNUM 17
  #define XMM1_REGNUM  35
  
  /* x86_64_register_raw_size_table[i] is the number of bytes of storage in
     GDB's register array occupied by register i.  */
! int x86_64_register_raw_size_table[X86_64_NUM_REGS] = {
!   8, 8, 8, 8,
!   8, 8, 8, 8,
!   8, 8, 8, 8,
!   8, 8, 8, 8,
!   8, 4,
!   10, 10, 10, 10,
!   10, 10, 10, 10,
!   4, 4, 4, 4,
!   4, 4, 4, 4,
!   16, 16, 16, 16,
!   16, 16, 16, 16,
!   16, 16, 16, 16,
!   16, 16, 16, 16,
!   4
  };
  
  /* Number of bytes of storage in the actual machine representation for
     register REGNO.  */
  int
  x86_64_register_raw_size (int regno)
  {
!   return x86_64_register_raw_size_table[regno];
  }
  
  /* x86_64_register_byte_table[i] is the offset into the register file of the
     start of register number i.  We initialize this from
!    x86_64_register_raw_size_table.  */
  int x86_64_register_byte_table[X86_64_NUM_REGS];
  
  /* Index within `registers' of the first byte of the space for register REGNO.  */
--- 35,132 ----
  
  /* Register numbers of various important registers.  */
  #define RAX_REGNUM 0
! #define RDX_REGNUM 3
  #define RDI_REGNUM 5
  #define EFLAGS_REGNUM 17
  #define XMM1_REGNUM  35
  
+ struct register_info { 
+   int	size;
+   char	*name;
+   struct type	**type;
+ };
+ 
  /* x86_64_register_raw_size_table[i] is the number of bytes of storage in
     GDB's register array occupied by register i.  */
! static struct register_info x86_64_register_info_table[] = {
!   { 8,  "rax", &builtin_type_int64 },
!   { 8,  "rbx", &builtin_type_int64 },
!   { 8,  "rcx", &builtin_type_int64 },
!   { 8,  "rdx", &builtin_type_int64 },
!   { 8,  "rsi", &builtin_type_int64 },
!   { 8,  "rdi", &builtin_type_int64 },
!   { 8,  "rbp", &builtin_type_void_func_ptr },
!   { 8,  "rsp", &builtin_type_void_func_ptr },
!   { 8,  "r8",  &builtin_type_int64 },
!   { 8,  "r9",  &builtin_type_int64 },
!   { 8,  "r10", &builtin_type_int64 },
!   { 8,  "r11", &builtin_type_int64 },
!   { 8,  "r12", &builtin_type_int64 },
!   { 8,  "r13", &builtin_type_int64 },
!   { 8,  "r14", &builtin_type_int64 },
!   { 8,  "r15", &builtin_type_int64 },
!   { 8,  "rip", &builtin_type_void_func_ptr },
!   { 4,  "eflags", &builtin_type_int32 },
!   { 4,  "ds",  &builtin_type_int32 },
!   { 4,  "es",  &builtin_type_int32 },
!   { 4,  "fs",  &builtin_type_int32 },
!   { 4,  "gs",  &builtin_type_int32 },
!   { 10, "st0", &builtin_type_i387_ext },
!   { 10, "st1", &builtin_type_i387_ext },
!   { 10, "st2", &builtin_type_i387_ext },
!   { 10, "st3", &builtin_type_i387_ext },
!   { 10, "st4", &builtin_type_i387_ext },
!   { 10, "st5", &builtin_type_i387_ext },
!   { 10, "st6", &builtin_type_i387_ext },
!   { 10, "st7", &builtin_type_i387_ext },
!   { 4,  "fctrl", &builtin_type_int32 },
!   { 4,  "fstat", &builtin_type_int32 },
!   { 4,  "ftag",  &builtin_type_int32 },
!   { 4,  "fiseg", &builtin_type_int32 },
!   { 4,  "fioff", &builtin_type_int32 },
!   { 4,  "foseg", &builtin_type_int32 },
!   { 4,  "fooff", &builtin_type_int32 },
!   { 4,  "fop",   &builtin_type_int32 },
!   { 16, "xmm0", &builtin_type_v4sf },
!   { 16, "xmm1", &builtin_type_v4sf },
!   { 16, "xmm2", &builtin_type_v4sf },
!   { 16, "xmm3", &builtin_type_v4sf },
!   { 16, "xmm4", &builtin_type_v4sf },
!   { 16, "xmm5", &builtin_type_v4sf },
!   { 16, "xmm6", &builtin_type_v4sf },
!   { 16, "xmm7", &builtin_type_v4sf },
!   { 16, "xmm8", &builtin_type_v4sf },
!   { 16, "xmm9", &builtin_type_v4sf },
!   { 16, "xmm10", &builtin_type_v4sf },
!   { 16, "xmm11", &builtin_type_v4sf },
!   { 16, "xmm12", &builtin_type_v4sf },
!   { 16, "xmm13", &builtin_type_v4sf },
!   { 16, "xmm14", &builtin_type_v4sf },
!   { 16, "xmm15", &builtin_type_v4sf },
!   { 4,  "mxcsr", &builtin_type_int32 }
  };
  
+ /* Number of all registers */
+ #define X86_64_NUM_REGS (sizeof (x86_64_register_info_table) / \
+   sizeof (x86_64_register_info_table[0]))
+ 
+ /* Number of general registers.  */
+ #define X86_64_NUM_GREGS (22)
+ 
+ int x86_64_num_regs = X86_64_NUM_REGS;
+ int x86_64_num_gregs = X86_64_NUM_GREGS;
+ 
  /* Number of bytes of storage in the actual machine representation for
     register REGNO.  */
  int
  x86_64_register_raw_size (int regno)
  {
!   return x86_64_register_info_table[regno].size;
  }
  
  /* x86_64_register_byte_table[i] is the offset into the register file of the
     start of register number i.  We initialize this from
!    x86_64_register_info_table.  */
  int x86_64_register_byte_table[X86_64_NUM_REGS];
  
  /* Index within `registers' of the first byte of the space for register REGNO.  */
*************** x86_64_register_byte (int regno)
*** 84,99 ****
  static struct type *
  x86_64_register_virtual_type (int regno)
  {
!   if (regno == PC_REGNUM || regno == SP_REGNUM)
!     return builtin_type_void_func_ptr;
!   if (IS_FP_REGNUM (regno))
!     return builtin_type_i387_ext;
!   if (IS_SSE_REGNUM (regno))
!     return builtin_type_v4sf;
!   if (IS_FPU_CTRL_REGNUM (regno) || regno == MXCSR_REGNUM
!       || regno == EFLAGS_REGNUM)
!     return builtin_type_int32;
!   return builtin_type_int64;
  }
  
  /* x86_64_register_convertible is true if register N's virtual format is
--- 141,147 ----
  static struct type *
  x86_64_register_virtual_type (int regno)
  {
!    return *x86_64_register_info_table[regno].type;
  }
  
  /* x86_64_register_convertible is true if register N's virtual format is
*************** x86_64_push_arguments (int nargs, struct
*** 557,571 ****
    int i;
    static int int_parameter_registers[INT_REGS] = {
      5 /*RDI*/, 4 /*RSI*/,
!     1 /*RDX*/, 2 /*RCX*/,
!     8 /*R8 */ , 9		/*R9 */
    };
    /* XMM0 - XMM15  */
    static int sse_parameter_registers[SSE_REGS] = {
!     34, 35, 36, 37,
!     38, 39, 40, 41,
!     42, 43, 44, 45,
!     46, 47, 48, 49
    };
    int stack_values_count = 0;
    int *stack_values;
--- 605,619 ----
    int i;
    static int int_parameter_registers[INT_REGS] = {
      5 /*RDI*/, 4 /*RSI*/,
!     3 /*RDX*/, 2 /*RCX*/,
!     8 /*R8 */, 9 /*R9 */
    };
    /* XMM0 - XMM15  */
    static int sse_parameter_registers[SSE_REGS] = {
!     XMM1_REGNUM-1, XMM1_REGNUM, XMM1_REGNUM+1, XMM1_REGNUM+2, 
!     XMM1_REGNUM+3, XMM1_REGNUM+4, XMM1_REGNUM+5, XMM1_REGNUM+6, 
!     XMM1_REGNUM+7, XMM1_REGNUM+8, XMM1_REGNUM+9, XMM1_REGNUM+10, 
!     XMM1_REGNUM+11, XMM1_REGNUM+12, XMM1_REGNUM+13, XMM1_REGNUM+14
    };
    int stack_values_count = 0;
    int *stack_values;
*************** x86_64_store_return_value (struct type *
*** 704,730 ****
  static char *
  x86_64_register_name (int reg_nr)
  {
!   static char *register_names[] = {
!     "rax", "rdx", "rcx", "rbx",
!     "rsi", "rdi", "rbp", "rsp",
!     "r8", "r9", "r10", "r11",
!     "r12", "r13", "r14", "r15",
!     "rip", "eflags",
!     "st0", "st1", "st2", "st3",
!     "st4", "st5", "st6", "st7",
!     "fctrl", "fstat", "ftag", "fiseg",
!     "fioff", "foseg", "fooff", "fop",
!     "xmm0", "xmm1", "xmm2", "xmm3",
!     "xmm4", "xmm5", "xmm6", "xmm7",
!     "xmm8", "xmm9", "xmm10", "xmm11",
!     "xmm12", "xmm13", "xmm14", "xmm15",
!     "mxcsr"
!   };
!   if (reg_nr < 0)
      return NULL;
!   if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
!     return NULL;
!   return register_names[reg_nr];
  }
  
  
--- 752,760 ----
  static char *
  x86_64_register_name (int reg_nr)
  {
!   if (reg_nr < 0 || reg_nr >= X86_64_NUM_REGS)
      return NULL;
!   return x86_64_register_info_table[reg_nr].name;
  }
  
  
*************** i386_gdbarch_init (struct gdbarch_info i
*** 826,831 ****
--- 856,862 ----
  {
    struct gdbarch *gdbarch;
    struct gdbarch_tdep *tdep;
+   int i, sum;
  
    /* Find a candidate among the list of pre-declared architectures. */
    for (arches = gdbarch_list_lookup_by_info (arches, &info);
*************** i386_gdbarch_init (struct gdbarch_info i
*** 904,913 ****
    set_gdbarch_register_raw_size (gdbarch, x86_64_register_raw_size);
    set_gdbarch_max_register_raw_size (gdbarch, 16);
    set_gdbarch_register_byte (gdbarch, x86_64_register_byte);
    /* Total amount of space needed to store our copies of the machine's register
       (SIZEOF_GREGS + SIZEOF_FPU_REGS + SIZEOF_FPU_CTRL_REGS + SIZEOF_SSE_REGS) */
!   set_gdbarch_register_bytes (gdbarch,
! 			      (18 * 8) + (8 * 10) + (8 * 4) + (16 * 16 + 4));
    set_gdbarch_register_virtual_size (gdbarch, generic_register_virtual_size);
    set_gdbarch_max_register_virtual_size (gdbarch, 16);
  
--- 935,946 ----
    set_gdbarch_register_raw_size (gdbarch, x86_64_register_raw_size);
    set_gdbarch_max_register_raw_size (gdbarch, 16);
    set_gdbarch_register_byte (gdbarch, x86_64_register_byte);
+ 
    /* Total amount of space needed to store our copies of the machine's register
       (SIZEOF_GREGS + SIZEOF_FPU_REGS + SIZEOF_FPU_CTRL_REGS + SIZEOF_SSE_REGS) */
!   for (i=0, sum=0; i < X86_64_NUM_REGS; i++)
!      sum += x86_64_register_info_table[i].size;
!   set_gdbarch_register_bytes (gdbarch, sum);
    set_gdbarch_register_virtual_size (gdbarch, generic_register_virtual_size);
    set_gdbarch_max_register_virtual_size (gdbarch, 16);
  
*************** i386_gdbarch_init (struct gdbarch_info i
*** 924,930 ****
    set_gdbarch_fp_regnum (gdbarch, 6);	/* (rbp) */
    set_gdbarch_pc_regnum (gdbarch, 16);	/* (rip) Contains program counter.  */
  
!   set_gdbarch_fp0_regnum (gdbarch, 18);	/* First FPU floating-point register.  */
  
    set_gdbarch_read_fp (gdbarch, cfi_read_fp);
    set_gdbarch_write_fp (gdbarch, cfi_write_fp);
--- 957,963 ----
    set_gdbarch_fp_regnum (gdbarch, 6);	/* (rbp) */
    set_gdbarch_pc_regnum (gdbarch, 16);	/* (rip) Contains program counter.  */
  
!   set_gdbarch_fp0_regnum (gdbarch, X86_64_NUM_GREGS);	/* First FPU floating-point register.  */
  
    set_gdbarch_read_fp (gdbarch, cfi_read_fp);
    set_gdbarch_write_fp (gdbarch, cfi_write_fp);
*************** _initialize_x86_64_tdep (void)
*** 1042,1048 ****
      for (i = 0; i < X86_64_NUM_REGS; i++)
        {
  	x86_64_register_byte_table[i] = offset;
! 	offset += x86_64_register_raw_size_table[i];
        }
    }
  
--- 1075,1081 ----
      for (i = 0; i < X86_64_NUM_REGS; i++)
        {
  	x86_64_register_byte_table[i] = offset;
! 	offset += x86_64_register_info_table[i].size;
        }
    }
  
Index: x86-64-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/x86-64-tdep.h,v
retrieving revision 1.2
diff -c -3 -p -r1.2 x86-64-tdep.h
*** x86-64-tdep.h	2002/03/10 18:16:26	1.2
--- x86-64-tdep.h	2002/03/26 16:56:52
***************
*** 25,35 ****
  
  #include "i386-tdep.h"
  
! /* Number of all registers */
! #define X86_64_NUM_REGS (51)
! 
! /* Number of general registers.  */
! #define X86_64_NUM_GREGS (18)
  
  gdbarch_frame_saved_pc_ftype x86_64_linux_frame_saved_pc;
  gdbarch_saved_pc_after_call_ftype x86_64_linux_saved_pc_after_call;
--- 25,32 ----
  
  #include "i386-tdep.h"
  
! extern int x86_64_num_regs;
! extern int x86_64_num_gregs;
  
  gdbarch_frame_saved_pc_ftype x86_64_linux_frame_saved_pc;
  gdbarch_saved_pc_after_call_ftype x86_64_linux_saved_pc_after_call;
Index: x86-64-linux-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/x86-64-linux-nat.c,v
retrieving revision 1.6
diff -c -3 -p -r1.6 x86-64-linux-nat.c
*** x86-64-linux-nat.c	2002/03/10 18:16:26	1.6
--- x86-64-linux-nat.c	2002/03/26 16:56:52
***************
*** 39,49 ****
     format and GDB's register array layout.  */
  
  static int x86_64_regmap[] = {
!   RAX, RDX, RCX, RBX,
    RSI, RDI, RBP, RSP,
    R8, R9, R10, R11,
    R12, R13, R14, R15,
!   RIP, EFLAGS
  };
  
  static unsigned long
--- 39,50 ----
     format and GDB's register array layout.  */
  
  static int x86_64_regmap[] = {
!   RAX, RBX, RCX, RDX,
    RSI, RDI, RBP, RSP,
    R8, R9, R10, R11,
    R12, R13, R14, R15,
!   RIP, EFLAGS, 
!   DS, ES, FS, GS
  };
  
  static unsigned long
*************** x86_64_linux_dr_get_status (void)
*** 125,131 ****
     the register sets used by `ptrace'.  */
  
  #define GETREGS_SUPPLIES(regno) \
!   (0 <= (regno) && (regno) <= 17)
  #define GETFPREGS_SUPPLIES(regno) \
    (FP0_REGNUM <= (regno) && (regno) <= MXCSR_REGNUM)
  
--- 126,132 ----
     the register sets used by `ptrace'.  */
  
  #define GETREGS_SUPPLIES(regno) \
!   (0 <= (regno) && (regno) < x86_64_num_gregs)
  #define GETFPREGS_SUPPLIES(regno) \
    (FP0_REGNUM <= (regno) && (regno) <= MXCSR_REGNUM)
  
*************** supply_gregset (elf_gregset_t * gregsetp
*** 144,150 ****
    elf_greg_t *regp = (elf_greg_t *) gregsetp;
    int i;
  
!   for (i = 0; i < X86_64_NUM_GREGS; i++)
      supply_register (i, (char *) (regp + x86_64_regmap[i]));
  }
  
--- 145,151 ----
    elf_greg_t *regp = (elf_greg_t *) gregsetp;
    int i;
  
!   for (i = 0; i < x86_64_num_gregs; i++)
      supply_register (i, (char *) (regp + x86_64_regmap[i]));
  }
  
*************** fill_gregset (elf_gregset_t * gregsetp, 
*** 158,164 ****
    elf_greg_t *regp = (elf_greg_t *) gregsetp;
    int i;
  
!   for (i = 0; i < X86_64_NUM_GREGS; i++)
      if ((regno == -1 || regno == i))
        read_register_gen (i, regp + x86_64_regmap[i]);
  }
--- 159,165 ----
    elf_greg_t *regp = (elf_greg_t *) gregsetp;
    int i;
  
!   for (i = 0; i < x86_64_num_gregs; i++)
      if ((regno == -1 || regno == i))
        read_register_gen (i, regp + x86_64_regmap[i]);
  }

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