This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils 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]

objdump -M for x86


Applying to mainline.  Note to gdb people: Some backwards compatibility
stuff can be removed when i386-tdep.c and x86-64-tdep are updated to use
the new (old!) print_insn_i386.

binutils/ChangeLog
	* doc/binutils.texi (objdump): Document x86 -M options.
include/ChangeLog
 	* dis-asm.h (print_insn_i386): Declare.
opcodes/ChangeLog
	* disassemble.c (disassembler): Call print_insn_i386.
	* i386-dis.c (SUFFIX_ALWAYS): Define.
	(struct dis_private): Add orig_sizeflag.
	(print_insn_i386): Make it a wrapper, calling..
	(print_insn): ..The old body of print_insn_i386.  Avoid longjmp
	warning without using volatile by moving orig_sizeflag to priv,
	and removing inbuf.  Parse disassembler_options.
	(print_insn_i386_att, print_insn_i386_intel): Move initialisation
	code to print_insn.
	(putop): Remove #ifdef SUFFIX_ALWAYS.

-- 
Alan Modra

Index: binutils/doc/binutils.texi
===================================================================
RCS file: /cvs/src/src/binutils/doc/binutils.texi,v
retrieving revision 1.8
diff -u -p -r1.8 binutils.texi
--- binutils.texi	2001/09/25 16:44:18	1.8
+++ binutils.texi	2001/11/14 02:29:01
@@ -1569,6 +1569,19 @@ using the switch @option{--disassembler-
 useful when attempting to disassemble thumb code produced by other
 compilers.
 
+For the x86, some of the options duplicate functions of the @option{-m}
+switch, but allow finer grained control.  Multiple selections from the
+following may be specified as a comma separated string.
+@option{x86_64}, @option{i386} and @option{i8086} select disassembly for
+the given architecture.  @option{intel} and @option{att} select between
+intel syntax mode and AT&T syntax mode.  @option{addr32},
+@option{addr16}, @option{data32} and @option{data16} specify the default
+address size and operand size.  These four options will be overridden if
+@option{x86_64}, @option{i386} or @option{i8086} appear later in the
+option string.  Lastly, @option{suffix}, when in AT&T mode,
+instructs the dissassembler to print a mnemonic suffix even when the
+suffix could be inferred by the operands.
+
 @item -p
 @itemx --private-headers
 Print information that is specific to the object file format.  The exact
Index: include/dis-asm.h
===================================================================
RCS file: /cvs/src/src/include/dis-asm.h,v
retrieving revision 1.26
diff -u -p -r1.26 dis-asm.h
--- dis-asm.h	2001/11/11 15:45:34	1.26
+++ dis-asm.h	2001/11/14 02:29:34
@@ -177,6 +177,7 @@ typedef int (*disassembler_ftype)
 
 extern int print_insn_big_mips		PARAMS ((bfd_vma, disassemble_info*));
 extern int print_insn_little_mips	PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_i386		PARAMS ((bfd_vma, disassemble_info *));
 extern int print_insn_i386_att		PARAMS ((bfd_vma, disassemble_info*));
 extern int print_insn_i386_intel	PARAMS ((bfd_vma, disassemble_info*));
 extern int print_insn_ia64		PARAMS ((bfd_vma, disassemble_info*));
Index: opcodes/disassemble.c
===================================================================
RCS file: /cvs/src/src/opcodes/disassemble.c,v
retrieving revision 1.28
diff -u -p -r1.28 disassemble.c
--- disassemble.c	2001/10/30 15:20:14	1.28
+++ disassemble.c	2001/11/14 02:29:52
@@ -150,11 +150,7 @@ disassembler (abfd)
 #endif
 #ifdef ARCH_i386
     case bfd_arch_i386:
-      if (bfd_get_mach (abfd) == bfd_mach_i386_i386_intel_syntax
-          || bfd_get_mach (abfd) == bfd_mach_x86_64_intel_syntax)
-        disassemble = print_insn_i386_intel;
-      else
-        disassemble = print_insn_i386_att;
+      disassemble = print_insn_i386;
       break;
 #endif
 #ifdef ARCH_i860
Index: opcodes/i386-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/i386-dis.c,v
retrieving revision 1.32
diff -u -p -r1.32 i386-dis.c
--- i386-dis.c	2001/11/13 01:03:55	1.32
+++ i386-dis.c	2001/11/14 02:29:54
@@ -52,7 +52,7 @@ Foundation, Inc., 59 Temple Place - Suit
 static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
 static void ckprefix PARAMS ((void));
 static const char *prefix_name PARAMS ((int, int));
-static int print_insn_i386 PARAMS ((bfd_vma, disassemble_info *));
+static int print_insn PARAMS ((bfd_vma, disassemble_info *));
 static void dofloat PARAMS ((int));
 static void OP_ST PARAMS ((int, int));
 static void OP_STi  PARAMS ((int, int));
@@ -101,6 +101,7 @@ struct dis_private {
   bfd_byte *max_fetched;
   bfd_byte the_buffer[MAXLEN];
   bfd_vma insn_start;
+  int orig_sizeflag;
   jmp_buf bailout;
 };
 
@@ -298,9 +299,7 @@ fetch_data (info, addr)
 #define loop_jcxz_flag NULL, loop_jcxz_mode
 
 /* bits in sizeflag */
-#if 0 /* Leave undefined until someone adds the extra flag to objdump.  */
 #define SUFFIX_ALWAYS 4
-#endif
 #define AFLAG 2
 #define DFLAG 1
 
@@ -442,9 +441,9 @@ struct dis386 {
    'N' => print 'n' if instruction has no wait "prefix"
    'O' => print 'd', or 'o'
    'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
-                              or suffix_always is true
-	  print 'q' if rex prefix is present.
-   'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always is true
+   .      or suffix_always is true.  print 'q' if rex prefix is present.
+   'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
+   .      is true
    'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
    'S' => print 'w', 'l' or 'q' if suffix_always is true
    'T' => print 'q' in 64bit mode and behave as 'P' otherwise
@@ -1837,25 +1836,17 @@ static char close_char;
 static char separator_char;
 static char scale_char;
 
+/* Here for backwards compatibility.  When gdb stops using
+   print_insn_i386_att and print_insn_i386_intel these functions can
+   disappear, and print_insn_i386 be merged into print_insn.  */
 int
 print_insn_i386_att (pc, info)
      bfd_vma pc;
      disassemble_info *info;
 {
   intel_syntax = 0;
-  names64 = att_names64;
-  names32 = att_names32;
-  names16 = att_names16;
-  names8 = att_names8;
-  names8rex = att_names8rex;
-  names_seg = att_names_seg;
-  index16 = att_index16;
-  open_char = '(';
-  close_char =  ')';
-  separator_char = ',';
-  scale_char = ',';
 
-  return print_insn_i386 (pc, info);
+  return print_insn (pc, info);
 }
 
 int
@@ -1864,52 +1855,128 @@ print_insn_i386_intel (pc, info)
      disassemble_info *info;
 {
   intel_syntax = 1;
-  names64 = intel_names64;
-  names32 = intel_names32;
-  names16 = intel_names16;
-  names8 = intel_names8;
-  names8rex = intel_names8rex;
-  names_seg = intel_names_seg;
-  index16 = intel_index16;
-  open_char = '[';
-  close_char = ']';
-  separator_char = '+';
-  scale_char = '*';
 
-  return print_insn_i386 (pc, info);
+  return print_insn (pc, info);
 }
 
-static int
+int
 print_insn_i386 (pc, info)
      bfd_vma pc;
      disassemble_info *info;
 {
+  intel_syntax = -1;
+
+  return print_insn (pc, info);
+}
+
+static int
+print_insn (pc, info)
+     bfd_vma pc;
+     disassemble_info *info;
+{
   const struct dis386 *dp;
   int i;
   int two_source_ops;
   char *first, *second, *third;
   int needcomma;
   unsigned char uses_SSE_prefix;
-  VOLATILE int sizeflag;
-  VOLATILE int orig_sizeflag;
-
+  int sizeflag;
+  const char *p;
   struct dis_private priv;
-  bfd_byte *inbuf = priv.the_buffer;
 
   mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax
 		|| info->mach == bfd_mach_x86_64);
 
+  if (intel_syntax == -1)
+    intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
+		    || info->mach == bfd_mach_x86_64_intel_syntax);
+
   if (info->mach == bfd_mach_i386_i386
       || info->mach == bfd_mach_x86_64
       || info->mach == bfd_mach_i386_i386_intel_syntax
       || info->mach == bfd_mach_x86_64_intel_syntax)
-    sizeflag = AFLAG | DFLAG;
+    priv.orig_sizeflag = AFLAG | DFLAG;
   else if (info->mach == bfd_mach_i386_i8086)
-    sizeflag = 0;
+    priv.orig_sizeflag = 0;
   else
     abort ();
-  orig_sizeflag = sizeflag;
 
+  for (p = info->disassembler_options; p != NULL; )
+    {
+      if (strncmp (p, "x86_64", 6) == 0)
+	{
+	  mode_64bit = 1;
+	  priv.orig_sizeflag = AFLAG | DFLAG;
+	}
+      else if (strncmp (p, "i386", 4) == 0)
+	{
+	  mode_64bit = 0;
+	  priv.orig_sizeflag = AFLAG | DFLAG;
+	}
+      else if (strncmp (p, "i8086", 5) == 0)
+	{
+	  mode_64bit = 0;
+	  priv.orig_sizeflag = 0;
+	}
+      else if (strncmp (p, "intel", 5) == 0)
+	{
+	  intel_syntax = 1;
+	}
+      else if (strncmp (p, "att", 3) == 0)
+	{
+	  intel_syntax = 0;
+	}
+      else if (strncmp (p, "addr", 4) == 0)
+	{
+	  if (p[4] == '1' && p[5] == '6')
+	    priv.orig_sizeflag &= ~AFLAG;
+	  else if (p[4] == '3' && p[5] == '2')
+	    priv.orig_sizeflag |= AFLAG;
+	}
+      else if (strncmp (p, "data", 4) == 0)
+	{
+	  if (p[4] == '1' && p[5] == '6')
+	    priv.orig_sizeflag &= ~DFLAG;
+	  else if (p[4] == '3' && p[5] == '2')
+	    priv.orig_sizeflag |= DFLAG;
+	}
+      else if (strncmp (p, "suffix", 6) == 0)
+	priv.orig_sizeflag |= SUFFIX_ALWAYS;
+
+      p = strchr (p, ',');
+      if (p != NULL)
+	p++;
+    }
+
+  if (intel_syntax)
+    {
+      names64 = intel_names64;
+      names32 = intel_names32;
+      names16 = intel_names16;
+      names8 = intel_names8;
+      names8rex = intel_names8rex;
+      names_seg = intel_names_seg;
+      index16 = intel_index16;
+      open_char = '[';
+      close_char = ']';
+      separator_char = '+';
+      scale_char = '*';
+    }
+  else
+    {
+      names64 = att_names64;
+      names32 = att_names32;
+      names16 = att_names16;
+      names8 = att_names8;
+      names8rex = att_names8rex;
+      names_seg = att_names_seg;
+      index16 = att_index16;
+      open_char = '(';
+      close_char =  ')';
+      separator_char = ',';
+      scale_char = ',';
+    }
+
   /* The output looks better if we put 7 bytes on a line, since that
      puts most long word instructions on a single line.  */
   info->bytes_per_line = 7;
@@ -1927,26 +1994,26 @@ print_insn_i386 (pc, info)
 
   the_info = info;
   start_pc = pc;
-  start_codep = inbuf;
-  codep = inbuf;
+  start_codep = priv.the_buffer;
+  codep = priv.the_buffer;
 
   if (setjmp (priv.bailout) != 0)
     {
       const char *name;
 
       /* Getting here means we tried for data but didn't get it.  That
-         means we have an incomplete instruction of some sort.  Just
-         print the first byte as a prefix or a .byte pseudo-op.  */
-      if (codep > inbuf)
+	 means we have an incomplete instruction of some sort.  Just
+	 print the first byte as a prefix or a .byte pseudo-op.  */
+      if (codep > priv.the_buffer)
 	{
-	  name = prefix_name (inbuf[0], orig_sizeflag);
+	  name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
 	  if (name != NULL)
 	    (*info->fprintf_func) (info->stream, "%s", name);
 	  else
 	    {
 	      /* Just print the first byte as a .byte instruction.  */
 	      (*info->fprintf_func) (info->stream, ".byte 0x%x",
-				     (unsigned int) inbuf[0]);
+				     (unsigned int) priv.the_buffer[0]);
 	    }
 
 	  return 1;
@@ -1959,6 +2026,7 @@ print_insn_i386 (pc, info)
   ckprefix ();
 
   insn_codep = codep;
+  sizeflag = priv.orig_sizeflag;
 
   FETCH_DATA (info, codep + 1);
   two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
@@ -1970,7 +2038,7 @@ print_insn_i386 (pc, info)
 
       /* fwait not followed by floating point instruction.  Print the
          first prefix, which is probably fwait itself.  */
-      name = prefix_name (inbuf[0], orig_sizeflag);
+      name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
       if (name == NULL)
 	name = INTERNAL_DISASSEMBLER_ERROR;
       (*info->fprintf_func) (info->stream, "%s", name);
@@ -2116,7 +2184,7 @@ print_insn_i386 (pc, info)
     {
       const char *name;
 
-      name = prefix_name (inbuf[0], orig_sizeflag);
+      name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
       if (name == NULL)
 	name = INTERNAL_DISASSEMBLER_ERROR;
       (*info->fprintf_func) (info->stream, "%s", name);
@@ -2125,7 +2193,7 @@ print_insn_i386 (pc, info)
   if (rex & ~rex_used)
     {
       const char *name;
-      name = prefix_name (rex | 0x40, orig_sizeflag);
+      name = prefix_name (rex | 0x40, priv.orig_sizeflag);
       if (name == NULL)
 	name = INTERNAL_DISASSEMBLER_ERROR;
       (*info->fprintf_func) (info->stream, "%s ", name);
@@ -2189,7 +2257,7 @@ print_insn_i386 (pc, info)
 	(*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
 						+ op_address[op_index[i]]), info);
       }
-  return codep - inbuf;
+  return codep - priv.the_buffer;
 }
 
 static const char *float_mem[] = {
@@ -2548,20 +2616,14 @@ putop (template, sizeflag)
 	case 'A':
           if (intel_syntax)
             break;
-	  if (mod != 3
-#ifdef SUFFIX_ALWAYS
-	      || (sizeflag & SUFFIX_ALWAYS)
-#endif
-	      )
+	  if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
 	    *obufp++ = 'b';
 	  break;
 	case 'B':
           if (intel_syntax)
             break;
-#ifdef SUFFIX_ALWAYS
 	  if (sizeflag & SUFFIX_ALWAYS)
 	    *obufp++ = 'b';
-#endif
 	  break;
 	case 'E':		/* For jcxz/jecxz */
 	  if (sizeflag & AFLAG)
@@ -2571,11 +2633,7 @@ putop (template, sizeflag)
 	case 'F':
           if (intel_syntax)
             break;
-	  if ((prefixes & PREFIX_ADDR)
-#ifdef SUFFIX_ALWAYS
-	      || (sizeflag & SUFFIX_ALWAYS)
-#endif
-	      )
+	  if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
 	    {
 	      if (sizeflag & AFLAG)
 		*obufp++ = 'l';
@@ -2602,10 +2660,8 @@ putop (template, sizeflag)
 	case 'L':
           if (intel_syntax)
             break;
-#ifdef SUFFIX_ALWAYS
 	  if (sizeflag & SUFFIX_ALWAYS)
 	    *obufp++ = 'l';
-#endif
 	  break;
 	case 'N':
 	  if ((prefixes & PREFIX_FWAIT) == 0)
@@ -2634,10 +2690,7 @@ putop (template, sizeflag)
             break;
 	  if ((prefixes & PREFIX_DATA)
 	      || (rex & REX_MODE64)
-#ifdef SUFFIX_ALWAYS
-	      || (sizeflag & SUFFIX_ALWAYS)
-#endif
-	      )
+	      || (sizeflag & SUFFIX_ALWAYS))
 	    {
 	      USED_REX (REX_MODE64);
 	      if (rex & REX_MODE64)
@@ -2665,11 +2718,7 @@ putop (template, sizeflag)
           if (intel_syntax)
             break;
 	  USED_REX (REX_MODE64);
-	  if (mod != 3
-#ifdef SUFFIX_ALWAYS
-	      || (sizeflag & SUFFIX_ALWAYS)
-#endif
-	      )
+	  if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
 	    {
 	      if (rex & REX_MODE64)
 		*obufp++ = 'q';
@@ -2718,7 +2767,6 @@ putop (template, sizeflag)
 	case 'S':
           if (intel_syntax)
             break;
-#ifdef SUFFIX_ALWAYS
 	  if (sizeflag & SUFFIX_ALWAYS)
 	    {
 	      if (rex & REX_MODE64)
@@ -2732,7 +2780,6 @@ putop (template, sizeflag)
 		  used_prefixes |= (prefixes & PREFIX_DATA);
 		}
 	    }
-#endif
 	  break;
 	case 'X':
 	  if (prefixes & PREFIX_DATA)


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