Add a symbol's value to the computed frag offset, rather than overwriting it.
[deliverable/binutils-gdb.git] / gdb / i386-tdep.c
index babae1c6a074a773ca5d9626c280ef9edcda3a6a..1fbf76ab966e9925f6375ecec68c975a734587d5 100644 (file)
@@ -46,6 +46,32 @@ static int gdb_print_insn_i386 (bfd_vma, disassemble_info *);
 
 void _initialize_i386_tdep PARAMS ((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 the
+   actual machine representation for 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";
@@ -58,9 +84,11 @@ static char *valid_flavors[] =
 };
 static char *disassembly_flavor = att_flavor;
 
+static void i386_print_register PARAMS ((char *, int, int));
+
 /* 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 set_disassembly_flavor PARAMS ((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
@@ -674,21 +702,47 @@ i386_extract_return_value (type, regbuf, valbuf)
      char regbuf[REGISTER_BYTES];
      char *valbuf;
 {
-/* On AIX, floating point values are returned in floating point registers.  */
-#ifdef I386_AIX_TARGET
+  /* On AIX and i386 GNU/Linux, floating point values are returned in
+     floating point registers.  */
+#if defined(I386_AIX_TARGET) || defined(I386_GNULINUX_TARGET)
   if (TYPE_CODE_FLT == TYPE_CODE (type))
     {
       double d;
       /* 387 %st(0), gcc uses this */
       floatformat_to_double (&floatformat_i387_ext,
+#if defined(FPDATA_REGNUM)
+                            &regbuf[REGISTER_BYTE (FPDATA_REGNUM)],
+#else /* !FPDATA_REGNUM */
                             &regbuf[REGISTER_BYTE (FP0_REGNUM)],
+#endif /* FPDATA_REGNUM */
+
                             &d);
       store_floating (valbuf, TYPE_LENGTH (type), d);
     }
   else
-#endif /* I386_AIX_TARGET */
+#endif /* I386_AIX_TARGET || I386_GNULINUX_TARGET*/
     {
+#if defined(LOW_RETURN_REGNUM)
+      int len = 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
+       error ("GDB bug: i386-tdep.c (i386_extract_return_value): Don't know how to find a return value %d bytes long", len);
+#else /* !LOW_RETURN_REGNUM */
       memcpy (valbuf, regbuf, TYPE_LENGTH (type));
+#endif /* LOW_RETURN_REGNUM */
     }
 }
 
@@ -931,9 +985,6 @@ set_disassembly_flavor_sfunc (args, from_tty, c)
      struct cmd_list_element *c;
 {
   set_disassembly_flavor ();
-
-  if (disassembly_flavor_hook != NULL)
-    disassembly_flavor_hook (args, from_tty);
 }
 
 static void
@@ -945,28 +996,50 @@ set_disassembly_flavor ()
     set_architecture_from_arch_mach (bfd_arch_i386, bfd_mach_i386_i386_intel_syntax);
 }
 
+
 void
 _initialize_i386_tdep ()
 {
-  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,
+                               (char *) &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.024596 seconds and 4 git commands to generate.