* hashtab.c: Change void * to PTR where necessary.
[deliverable/binutils-gdb.git] / gdb / i386-tdep.c
index 3e50ca89edc73f51133896344843cf3fe5a3b15a..8aaf651dba330ac336bbe20993fea24a404bb9c6 100644 (file)
 #include "symtab.h"
 #include "gdbcmd.h"
 #include "command.h"
+#include "arch-utils.h"
 
-static long i386_get_frame_setup PARAMS ((CORE_ADDR));
+static long i386_get_frame_setup (CORE_ADDR);
 
-static void i386_follow_jump PARAMS ((void));
+static void i386_follow_jump (void);
 
-static void codestream_read PARAMS ((unsigned char *, int));
+static void codestream_read (unsigned char *, int);
 
-static void codestream_seek PARAMS ((CORE_ADDR));
+static void codestream_seek (CORE_ADDR);
 
-static unsigned char codestream_fill PARAMS ((int));
+static unsigned char codestream_fill (int);
 
-CORE_ADDR skip_trampoline_code PARAMS ((CORE_ADDR, char *));
+CORE_ADDR skip_trampoline_code (CORE_ADDR, char *);
 
 static int gdb_print_insn_i386 (bfd_vma, disassemble_info *);
 
-void _initialize_i386_tdep PARAMS ((void));
+void _initialize_i386_tdep (void);
+
+/* i386_register_byte[i] is the offset into the register file of the
+   start of register number i.  We initialize this from
+   i386_register_raw_size.  */
+int i386_register_byte[MAX_NUM_REGS];
+
+/* i386_register_raw_size[i] is the number of bytes of storage in
+   GDB's register array occupied by register i.  */
+int i386_register_raw_size[MAX_NUM_REGS] = {
+   4,  4,  4,  4,
+   4,  4,  4,  4,
+   4,  4,  4,  4,
+   4,  4,  4,  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,
+   4
+};
+
+/* i386_register_virtual_size[i] is the size in bytes of the virtual
+   type of register i.  */
+int i386_register_virtual_size[MAX_NUM_REGS];
+
 
 /* This is the variable the is set with "set disassembly-flavor",
    and its legitimate values. */
-static char att_flavor[] = "att";
-static char intel_flavor[] = "intel";
-static char *valid_flavors[] =
+static const char att_flavor[] = "att";
+static const char intel_flavor[] = "intel";
+static const char *valid_flavors[] =
 {
   att_flavor,
   intel_flavor,
   NULL
 };
-static char *disassembly_flavor = att_flavor;
+static const char *disassembly_flavor = att_flavor;
 
-/* This is used to keep the bfd arch_info in sync with the disassembly flavor.  */
-static void set_disassembly_flavor_sfunc PARAMS ((char *, int, struct cmd_list_element *));
-static void set_disassembly_flavor ();
+static void i386_print_register (char *, int, int);
 
-void (*disassembly_flavor_hook) PARAMS ((char *args, int from_tty));
+/* This is used to keep the bfd arch_info in sync with the disassembly flavor.  */
+static void set_disassembly_flavor_sfunc (char *, int,
+                                         struct cmd_list_element *);
+static void set_disassembly_flavor (void);
 
 /* Stdio style buffering was used to minimize calls to ptrace, but this
    buffering did not take into account that the code section being accessed
@@ -95,8 +123,7 @@ static int codestream_cnt;
                         codestream_fill(0) : codestream_buf[codestream_off++])
 
 static unsigned char
-codestream_fill (peek_flag)
-     int peek_flag;
+codestream_fill (int peek_flag)
 {
   codestream_addr = codestream_next_addr;
   codestream_next_addr += CODESTREAM_BUFSIZ;
@@ -111,8 +138,7 @@ codestream_fill (peek_flag)
 }
 
 static void
-codestream_seek (place)
-     CORE_ADDR place;
+codestream_seek (CORE_ADDR place)
 {
   codestream_next_addr = place / CODESTREAM_BUFSIZ;
   codestream_next_addr *= CODESTREAM_BUFSIZ;
@@ -123,9 +149,7 @@ codestream_seek (place)
 }
 
 static void
-codestream_read (buf, count)
-     unsigned char *buf;
-     int count;
+codestream_read (unsigned char *buf, int count)
 {
   unsigned char *p;
   int i;
@@ -137,7 +161,7 @@ codestream_read (buf, count)
 /* next instruction is a jump, move to target */
 
 static void
-i386_follow_jump ()
+i386_follow_jump (void)
 {
   unsigned char buf[4];
   long delta;
@@ -195,8 +219,7 @@ i386_follow_jump ()
  */
 
 static long
-i386_get_frame_setup (pc)
-     CORE_ADDR pc;
+i386_get_frame_setup (CORE_ADDR pc)
 {
   unsigned char op;
 
@@ -347,8 +370,7 @@ i386_get_frame_setup (pc)
    Can return -1, meaning no way to tell.  */
 
 int
-i386_frame_num_args (fi)
-     struct frame_info *fi;
+i386_frame_num_args (struct frame_info *fi)
 {
 #if 1
   return -1;
@@ -449,9 +471,7 @@ i386_frame_num_args (fi)
  */
 
 void
-i386_frame_find_saved_regs (fip, fsrp)
-     struct frame_info *fip;
-     struct frame_saved_regs *fsrp;
+i386_frame_init_saved_regs (struct frame_info *fip)
 {
   long locals = -1;
   unsigned char op;
@@ -460,7 +480,10 @@ i386_frame_find_saved_regs (fip, fsrp)
   CORE_ADDR pc;
   int i;
 
-  memset (fsrp, 0, sizeof *fsrp);
+  if (fip->saved_regs)
+    return;
+
+  frame_saved_regs_zalloc (fip);
 
   /* if frame is the end of a dummy, compute where the
    * beginning would be
@@ -475,7 +498,7 @@ i386_frame_find_saved_regs (fip, fsrp)
       for (i = 0; i < NUM_REGS; i++)
        {
          adr -= REGISTER_RAW_SIZE (i);
-         fsrp->regs[i] = adr;
+         fip->saved_regs[i] = adr;
        }
       return;
     }
@@ -494,23 +517,22 @@ i386_frame_find_saved_regs (fip, fsrp)
            break;
 #ifdef I386_REGNO_TO_SYMMETRY
          /* Dynix uses different internal numbering.  Ick.  */
-         fsrp->regs[I386_REGNO_TO_SYMMETRY (op - 0x50)] = adr;
+         fip->saved_regs[I386_REGNO_TO_SYMMETRY (op - 0x50)] = adr;
 #else
-         fsrp->regs[op - 0x50] = adr;
+         fip->saved_regs[op - 0x50] = adr;
 #endif
          adr -= 4;
        }
     }
 
-  fsrp->regs[PC_REGNUM] = fip->frame + 4;
-  fsrp->regs[FP_REGNUM] = fip->frame;
+  fip->saved_regs[PC_REGNUM] = fip->frame + 4;
+  fip->saved_regs[FP_REGNUM] = fip->frame;
 }
 
 /* return pc of first real instruction */
 
 int
-i386_skip_prologue (pc)
-     int pc;
+i386_skip_prologue (int pc)
 {
   unsigned char op;
   int i;
@@ -591,7 +613,7 @@ i386_skip_prologue (pc)
 }
 
 void
-i386_push_dummy_frame ()
+i386_push_dummy_frame (void)
 {
   CORE_ADDR sp = read_register (SP_REGNUM);
   int regnum;
@@ -608,21 +630,41 @@ i386_push_dummy_frame ()
   write_register (SP_REGNUM, sp);
 }
 
+/* Insert the (relative) function address into the call sequence
+   stored at DYMMY.  */
+
+void
+i386_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
+                    value_ptr *args, struct type *type, int gcc_p)
+{
+  int from, to, delta, loc;
+
+  loc = (int)(read_register (SP_REGNUM) - CALL_DUMMY_LENGTH);
+  from = loc + 5;
+  to = (int)(fun);
+  delta = to - from;
+
+  *((char *)(dummy) + 1) = (delta & 0xff);
+  *((char *)(dummy) + 2) = ((delta >> 8) & 0xff);
+  *((char *)(dummy) + 3) = ((delta >> 16) & 0xff);
+  *((char *)(dummy) + 4) = ((delta >> 24) & 0xff);
+}
+
 void
-i386_pop_frame ()
+i386_pop_frame (void)
 {
   struct frame_info *frame = get_current_frame ();
   CORE_ADDR fp;
   int regnum;
-  struct frame_saved_regs fsr;
   char regbuf[MAX_REGISTER_RAW_SIZE];
 
   fp = FRAME_FP (frame);
-  get_frame_saved_regs (frame, &fsr);
+  i386_frame_init_saved_regs (frame);
+
   for (regnum = 0; regnum < NUM_REGS; regnum++)
     {
       CORE_ADDR adr;
-      adr = fsr.regs[regnum];
+      adr = frame->saved_regs[regnum];
       if (adr)
        {
          read_memory (adr, regbuf, REGISTER_RAW_SIZE (regnum));
@@ -644,8 +686,7 @@ i386_pop_frame ()
    This routine returns true on success. */
 
 int
-get_longjmp_target (pc)
-     CORE_ADDR *pc;
+get_longjmp_target (CORE_ADDR *pc)
 {
   char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
   CORE_ADDR sp, jb_addr;
@@ -670,37 +711,101 @@ get_longjmp_target (pc)
 
 #endif /* GET_LONGJMP_TARGET */
 
+/* These registers are used for returning integers (and on some
+   targets also for returning `struct' and `union' values when their
+   size and alignment match an integer type.  */
+#define LOW_RETURN_REGNUM 0    /* %eax */
+#define HIGH_RETURN_REGNUM 2   /* %edx */
+
+/* Extract from an array REGBUF containing the (raw) register state, a
+   function return value of TYPE, and copy that, in virtual format,
+   into VALBUF.  */
+
 void
-i386_extract_return_value (type, regbuf, valbuf)
-     struct type *type;
-     char regbuf[REGISTER_BYTES];
-     char *valbuf;
+i386_extract_return_value (struct type *type, char *regbuf, char *valbuf)
 {
-/* On AIX, floating point values are returned in floating point registers.  */
-#ifdef I386_AIX_TARGET
+  int len = TYPE_LENGTH (type);
+
   if (TYPE_CODE_FLT == TYPE_CODE (type))
     {
-      double d;
-      /* 387 %st(0), gcc uses this */
-      floatformat_to_double (&floatformat_i387_ext,
-                            &regbuf[REGISTER_BYTE (FP0_REGNUM)],
-                            &d);
-      store_floating (valbuf, TYPE_LENGTH (type), d);
+      if (NUM_FREGS == 0)
+       {
+         warning ("Cannot find floating-point return value.");
+         memset (valbuf, 0, len);
+       }
+
+      /* Floating-point return values can be found in %st(0).  */
+      if (len == TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT
+         && TARGET_LONG_DOUBLE_FORMAT == &floatformat_i387_ext)
+       {
+         /* Copy straight over, but take care of the padding.  */
+         memcpy (valbuf, &regbuf[REGISTER_BYTE (FP0_REGNUM)],
+                 FPU_REG_RAW_SIZE);
+         memset (valbuf + FPU_REG_RAW_SIZE, 0, len - FPU_REG_RAW_SIZE);
+       }
+      else
+       {
+         /* Convert the extended floating-point number found in
+             %st(0) to the desired type.  This is probably not exactly
+             how it would happen on the target itself, but it is the
+             best we can do.  */
+         DOUBLEST val;
+         floatformat_to_doublest (&floatformat_i387_ext,
+                                  &regbuf[REGISTER_BYTE (FP0_REGNUM)], &val);
+         store_floating (valbuf, TYPE_LENGTH (type), val);
+       }
     }
   else
-#endif /* I386_AIX_TARGET */
     {
-      memcpy (valbuf, regbuf, TYPE_LENGTH (type));
+      int low_size = REGISTER_RAW_SIZE (LOW_RETURN_REGNUM);
+      int high_size = REGISTER_RAW_SIZE (HIGH_RETURN_REGNUM);
+
+      if (len <= low_size)
+       memcpy (valbuf, &regbuf[REGISTER_BYTE (LOW_RETURN_REGNUM)], len);
+      else if (len <= (low_size + high_size))
+       {
+         memcpy (valbuf,
+                 &regbuf[REGISTER_BYTE (LOW_RETURN_REGNUM)], low_size);
+         memcpy (valbuf + low_size,
+                 &regbuf[REGISTER_BYTE (HIGH_RETURN_REGNUM)], len - low_size);
+       }
+      else
+       internal_error ("Cannot extract return value of %d bytes long.", len);
     }
 }
 
+/* Convert data from raw format for register REGNUM in buffer FROM to
+   virtual format with type TYPE in buffer TO.  In principle both
+   formats are identical except that the virtual format has two extra
+   bytes appended that aren't used.  We set these to zero.  */
+
+void
+i386_register_convert_to_virtual (int regnum, struct type *type,
+                                 char *from, char *to)
+{
+  /* Copy straight over, but take care of the padding.  */
+  memcpy (to, from, FPU_REG_RAW_SIZE);
+  memset (to + FPU_REG_RAW_SIZE, 0, TYPE_LENGTH (type) - FPU_REG_RAW_SIZE);
+}
+
+/* Convert data from virtual format with type TYPE in buffer FROM to
+   raw format for register REGNUM in buffer TO.  Simply omit the two
+   unused bytes.  */
+
+void
+i386_register_convert_to_raw (struct type *type, int regnum,
+                             char *from, char *to)
+{
+  memcpy (to, from, FPU_REG_RAW_SIZE);
+}
+
+\f     
 #ifdef I386V4_SIGTRAMP_SAVED_PC
 /* Get saved user PC for sigtramp from the pushed ucontext on the stack
    for all three variants of SVR4 sigtramps.  */
 
 CORE_ADDR
-i386v4_sigtramp_saved_pc (frame)
-     struct frame_info *frame;
+i386v4_sigtramp_saved_pc (struct frame_info *frame)
 {
   CORE_ADDR saved_pc_offset = 4;
   char *name = NULL;
@@ -722,13 +827,13 @@ i386v4_sigtramp_saved_pc (frame)
 }
 #endif /* I386V4_SIGTRAMP_SAVED_PC */
 
+
 #ifdef STATIC_TRANSFORM_NAME
 /* SunPRO encodes the static variables.  This is not related to C++ mangling,
    it is done for C too.  */
 
 char *
-sunpro_static_transform_name (name)
-     char *name;
+sunpro_static_transform_name (char *name)
 {
   char *p;
   if (IS_STATIC_TRANSFORM_NAME (name))
@@ -753,9 +858,7 @@ sunpro_static_transform_name (name)
 /* Stuff for WIN32 PE style DLL's but is pretty generic really. */
 
 CORE_ADDR
-skip_trampoline_code (pc, name)
-     CORE_ADDR pc;
-     char *name;
+skip_trampoline_code (CORE_ADDR pc, char *name)
 {
   if (pc && read_memory_unsigned_integer (pc, 2) == 0x25ff)    /* jmp *(dest) */
     {
@@ -775,9 +878,7 @@ skip_trampoline_code (pc, name)
 }
 
 static int
-gdb_print_insn_i386 (memaddr, info)
-     bfd_vma memaddr;
-     disassemble_info *info;
+gdb_print_insn_i386 (bfd_vma memaddr, disassemble_info *info)
 {
   if (disassembly_flavor == att_flavor)
     return print_insn_i386_att (memaddr, info);
@@ -793,19 +894,14 @@ gdb_print_insn_i386 (memaddr, info)
    command, and does that.  */
 
 static void
-set_disassembly_flavor_sfunc (args, from_tty, c)
-     char *args;
-     int from_tty;
-     struct cmd_list_element *c;
+set_disassembly_flavor_sfunc (char *args, int from_tty,
+                             struct cmd_list_element *c)
 {
   set_disassembly_flavor ();
-
-  if (disassembly_flavor_hook != NULL)
-    disassembly_flavor_hook (args, from_tty);
 }
 
 static void
-set_disassembly_flavor ()
+set_disassembly_flavor (void)
 {
   if (disassembly_flavor == att_flavor)
     set_architecture_from_arch_mach (bfd_arch_i386, bfd_mach_i386_i386);
@@ -813,28 +909,50 @@ set_disassembly_flavor ()
     set_architecture_from_arch_mach (bfd_arch_i386, bfd_mach_i386_i386_intel_syntax);
 }
 
+
 void
-_initialize_i386_tdep ()
+_initialize_i386_tdep (void)
 {
-  struct cmd_list_element *new_cmd;
+  /* Initialize the table saying where each register starts in the
+     register file.  */
+  {
+    int i, offset;
+
+    offset = 0;
+    for (i = 0; i < MAX_NUM_REGS; i++)
+      {
+       i386_register_byte[i] = offset;
+       offset += i386_register_raw_size[i];
+      }
+  }
+
+  /* Initialize the table of virtual register sizes.  */
+  {
+    int i;
+
+    for (i = 0; i < MAX_NUM_REGS; i++)
+      i386_register_virtual_size[i] = TYPE_LENGTH (REGISTER_VIRTUAL_TYPE (i));
+  }
 
   tm_print_insn = gdb_print_insn_i386;
   tm_print_insn_info.mach = bfd_lookup_arch (bfd_arch_i386, 0)->mach;
 
   /* Add the variable that controls the disassembly flavor */
+  {
+    struct cmd_list_element *new_cmd;
 
-  new_cmd = add_set_enum_cmd ("disassembly-flavor", no_class,
-                             valid_flavors,
-                             (char *) &disassembly_flavor,
-                             "Set the disassembly flavor, the valid values are \"att\" and \"intel\", \
+    new_cmd = add_set_enum_cmd ("disassembly-flavor", no_class,
+                               valid_flavors,
+                               &disassembly_flavor,
+                               "Set the disassembly flavor, the valid values are \"att\" and \"intel\", \
 and the default value is \"att\".",
-                             &setlist);
-  new_cmd->function.sfunc = set_disassembly_flavor_sfunc;
-  add_show_from_set (new_cmd, &showlist);
+                               &setlist);
+    new_cmd->function.sfunc = set_disassembly_flavor_sfunc;
+    add_show_from_set (new_cmd, &showlist);
+  }
 
   /* Finally, initialize the disassembly flavor to the default given
      in the disassembly_flavor variable */
 
   set_disassembly_flavor ();
-
 }
This page took 0.029333 seconds and 4 git commands to generate.