Joel Sherrill (joel@OARcorp.com)
[deliverable/binutils-gdb.git] / gdb / i386-tdep.c
index 7ee239b24f7ccb4c1b858bc646368164d706ff7b..228b1acdde7ce5e5638cb6298bd67f3fd74d61cb 100644 (file)
@@ -1,5 +1,6 @@
 /* Intel 386 target-dependent stuff.
-   Copyright (C) 1988, 1989, 1991, 1994, 1995, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1988, 1989, 1991, 1994, 1995, 1996, 1998
+   Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -26,6 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "floatformat.h"
 #include "symtab.h"
 #include "gdbcmd.h"
+#include "command.h"
 
 static long i386_get_frame_setup PARAMS ((CORE_ADDR));
 
@@ -37,6 +39,29 @@ static void codestream_seek PARAMS ((CORE_ADDR));
 
 static unsigned char codestream_fill PARAMS ((int));
 
+CORE_ADDR skip_trampoline_code PARAMS ((CORE_ADDR, char *));
+
+static int gdb_print_insn_i386 (bfd_vma, disassemble_info *);
+
+void _initialize_i386_tdep PARAMS ((void));
+
+/* 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[] = {
+  att_flavor,
+  intel_flavor,
+  NULL
+};
+static 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 ();
+
+void (*disassembly_flavor_hook) PARAMS((char *args, int from_tty));
+
 /* Stdio style buffering was used to minimize calls to ptrace, but this
    buffering did not take into account that the code section being accessed
    may not be an even number of buffers long (even if the buffer is only
@@ -210,6 +235,39 @@ i386_get_frame_setup (pc)
       op = codestream_get (); /* update next opcode */
     }
 
+  if (op == 0x68 || op == 0x6a)
+    {
+      /*
+       * this function may start with
+       *
+       *   pushl constant
+       *   call _probe
+       *   addl $4, %esp
+       *      followed by 
+       *     pushl %ebp
+       *     etc.
+       */
+      int pos;
+      unsigned char buf[8];
+
+      /* Skip past the pushl instruction; it has either a one-byte 
+         or a four-byte operand, depending on the opcode.  */
+      pos = codestream_tell ();
+      if (op == 0x68)
+       pos += 4;
+      else
+       pos += 1;
+      codestream_seek (pos);
+
+      /* Read the following 8 bytes, which should be "call _probe" (6 bytes)
+         followed by "addl $4,%esp" (2 bytes).  */
+      codestream_read (buf, sizeof (buf));
+      if (buf[0] == 0xe8 && buf[6] == 0xc4 && buf[7] == 0x4)
+       pos += sizeof (buf);
+      codestream_seek (pos);
+      op = codestream_get (); /* update next opcode */
+    }
+
   if (op == 0x55)              /* pushl %ebp */
     {                  
       /* check for movl %esp, %ebp - can be written two ways */
@@ -314,7 +372,7 @@ i386_frame_num_args (fi)
        nameless arguments.  */
     return -1;
 
-  pfi = get_prev_frame_info (fi);                      
+  pfi = get_prev_frame (fi);                   
   if (pfi == 0)
     {
       /* Note:  this can happen if we are looking at the frame for
@@ -391,10 +449,11 @@ i386_frame_find_saved_regs (fip, fsrp)
      struct frame_info *fip;
      struct frame_saved_regs *fsrp;
 {
-  long locals;
+  long locals = -1;
   unsigned char op;
   CORE_ADDR dummy_bottom;
   CORE_ADDR adr;
+  CORE_ADDR pc;
   int i;
   
   memset (fsrp, 0, sizeof *fsrp);
@@ -417,7 +476,9 @@ i386_frame_find_saved_regs (fip, fsrp)
       return;
     }
   
-  locals = i386_get_frame_setup (get_pc_function_start (fip->pc));
+  pc = get_pc_function_start (fip->pc);
+  if (pc != 0)
+    locals = i386_get_frame_setup (pc);
   
   if (locals >= 0) 
     {
@@ -656,6 +717,32 @@ 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;
+{
+  char *p;
+  if (IS_STATIC_TRANSFORM_NAME (name))
+    {
+      /* For file-local statics there will be a period, a bunch
+        of junk (the contents of which match a string given in the
+        N_OPT), a period and the name.  For function-local statics
+        there will be a bunch of junk (which seems to change the
+        second character from 'A' to 'B'), a period, the name of the
+        function, and the name.  So just skip everything before the
+        last period.  */
+      p = strrchr (name, '.');
+      if (p != NULL)
+       name = p + 1;
+    }
+  return name;
+}
+#endif /* STATIC_TRANSFORM_NAME */
+
 
 
 /* Stuff for WIN32 PE style DLL's but is pretty generic really. */
@@ -682,34 +769,67 @@ skip_trampoline_code (pc, name)
   return 0;                    /* not a trampoline */
 }
 
-static char *x86_assembly_types[] = {"i386", "i8086", NULL};
-static char *x86_assembly_result = "i386";
+static int
+gdb_print_insn_i386 (memaddr, info)
+     bfd_vma memaddr;
+     disassemble_info * info;
+{
+  if (disassembly_flavor == att_flavor)
+    return print_insn_i386_att (memaddr, info);
+  else if (disassembly_flavor == intel_flavor)
+    return print_insn_i386_intel (memaddr, info);
+  /* Never reached - disassembly_flavour is always either att_flavor
+     or intel_flavor */
+  abort ();
+}
+
+/* If the disassembly mode is intel, we have to also switch the
+   bfd mach_type.  This function is run in the set disassembly_flavor
+   command, and does that.  */
 
 static void
-set_assembly_language_command (ignore, from_tty, c)
-     char *ignore;
+set_disassembly_flavor_sfunc (args, from_tty, c)
+     char *args;
      int from_tty;
      struct cmd_list_element *c;
 {
-  if (strcmp (x86_assembly_result, "i386") == 0)
-    tm_print_insn = print_insn_i386;
-  else
-    tm_print_insn = print_insn_i8086;
+  set_disassembly_flavor ();
+  
+  if (disassembly_flavor_hook != NULL)
+    disassembly_flavor_hook(args, from_tty);
+}
+
+static void
+set_disassembly_flavor ()
+{
+  if (disassembly_flavor == att_flavor)
+    set_architecture_from_arch_mach (bfd_arch_i386, bfd_mach_i386_i386);
+  else if (disassembly_flavor == intel_flavor)
+    set_architecture_from_arch_mach (bfd_arch_i386, bfd_mach_i386_i386_intel_syntax);
 }
 
 void
 _initialize_i386_tdep ()
 {
-  struct cmd_list_element *cmd;
-
-  tm_print_insn = print_insn_i386;
-
-  cmd = add_set_enum_cmd ("assembly-language", class_obscure,
-                         x86_assembly_types, (char *)&x86_assembly_result,
-                         "Set x86 instruction set to use for disassembly.\n\
-This value can be set to either i386 or i8086 to change how instructions are disassembled.",
-                         &setlist);
-  add_show_from_set (cmd, &showlist);
+  struct cmd_list_element *new_cmd;
+  
+  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 */
+
+  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);
+  
+  /* Finally, initialize the disassembly flavor to the default given
+     in the disassembly_flavor variable */
 
-  cmd->function.sfunc = set_assembly_language_command;
+  set_disassembly_flavor ();
+  
 }
This page took 0.02615 seconds and 4 git commands to generate.