Add -M command line switch to objdump - text of switch is passed on to disassembler
authorNick Clifton <nickc@redhat.com>
Wed, 16 Jun 1999 02:24:36 +0000 (02:24 +0000)
committerNick Clifton <nickc@redhat.com>
Wed, 16 Jun 1999 02:24:36 +0000 (02:24 +0000)
Add support for register name set selection ot ARM disassembler.

binutils/ChangeLog
binutils/NEWS
binutils/binutils.texi
binutils/objdump.c
include/ChangeLog
include/dis-asm.h
opcodes/ChangeLog
opcodes/arm-dis.c
opcodes/disassemble.c

index d3e1ba360642fce5abb231b16bd578b4119db082..83feb18d8c49524afab2f5c8709e32bb118a8054 100644 (file)
@@ -1,3 +1,17 @@
+1999-06-14  Nick Clifton  <nickc@cygnus.com>
+
+       * objdump.c (disassembler_options): New variable.
+       (usage): Document new -M/--disassembler-options option.
+       (long_options): Add --disassembler-options.
+       (disassemble_data): Initialise disassembler_options field of
+       disassembler_info structure.
+       (main): Add parsing of -M option.
+       
+       * binutils.texi: Document new command line switch to objdump.
+
+       * NEWS: Describe new command line switch to objdump.
+
+
 Mon Jun 14 10:27:54 1999  Andreas Schwab  <schwab@issan.cs.uni-dortmund.de>
 
        * binutils.texi: Fix typos.
index 7c39501086155ad4298c5b9e1908a31c6f6a9e07..eb27ad5447619b4c7c097cdc62bd87017fd91911 100644 (file)
@@ -2,6 +2,11 @@
 
 Changes in binutils 2.10:
 
+* New command line switch to objdump -M (or --disassembler-options) which takes
+  a parameter which can then be interpreted on a per-target basis by the
+  disassembler.  Used by ARM targets to select register name sets, ISA, APCS or
+  raw verions.
+  
 * objdump support for -mi386:intel which causes disassembly to be displayed
   with intel syntax.
 
index 73bba55742bdc28b4960d84a22bdd97e04f1cffb..535df3f6b8a0f0a16ec7119dd44e407e91e13631 100644 (file)
@@ -1137,6 +1137,7 @@ objdump [ -a | --archive-headers ]
         [ -j @var{section} | --section=@var{section} ]
         [ -l | --line-numbers ] [ -S | --source ]
         [ -m @var{machine} | --architecture=@var{machine} ]
+        [ -M @var{options} | --disassembler-options=@var{options}]
         [ -p | --private-headers ]
         [ -r | --reloc ] [ -R | --dynamic-reloc ]
         [ -s | --full-contents ]  [ --stabs ]
@@ -1295,6 +1296,21 @@ can be useful when disassembling object files which do not describe
 architecture information, such as S-records.  You can list the available
 architectures with the @samp{-i} option.
 
+@item -M @var{options}
+@itemx --disassembler-options=@var{options}
+Pass target specific information to the disassembler.  Only supported on
+some targets.
+
+If the target is an ARM architecture then this switch can be used to
+select which register name set is used during disassembler.  Specifying
+@samp{--disassembler-options=reg-name-std} (the default) will select the
+register names as used in ARM's instruction set documentation, but with
+register 13 called 'sp', register 14 called 'lr' and register 15 called
+'pc'.  Specifying @samp{--disassembler-options=reg-names-apcs} will
+select the name set used by the ARM Procedure Call Standard, whilst
+specifying @samp{--disassembler-options=reg-names-raw} will just use
+@samp{r} followed by the register number.
+
 @item -p
 @itemx --private-headers
 Print information that is specific to the object file format.  The exact
index 40c68cc3b3303be1888ee8f59fdd67c145e46d59..b7ee5d6283af1c899a348ecc89f0da33ff39bfa0 100644 (file)
@@ -83,6 +83,9 @@ struct objdump_disasm_info {
 /* Architecture to disassemble for, or default if NULL.  */
 static char *machine = (char *) NULL;
 
+/* Target specific options to the disassembler.  */
+static char *disassembler_options = (char *) NULL;
+
 /* Endianness to disassemble for, or default if BFD_ENDIAN_UNKNOWN.  */
 static enum bfd_endian endian = BFD_ENDIAN_UNKNOWN;
 
@@ -217,7 +220,8 @@ usage (stream, status)
      int status;
 {
   fprintf (stream, _("\
-Usage: %s [-ahifCdDprRtTxsSlw] [-b bfdname] [-m machine] [-j section-name]\n\
+Usage: %s [-ahifCdDprRtTxsSlw] [-b bfdname] [-m machine] \n\
+       [-j section-name] [-M disassembler-options]\n\
        [--archive-headers] [--target=bfdname] [--debugging] [--disassemble]\n\
        [--disassemble-all] [--disassemble-zeroes] [--file-headers]\n\
        [--section-headers] [--headers]\n\
@@ -255,6 +259,7 @@ static struct option long_options[]=
   {"demangle", no_argument, &do_demangle, 1},
   {"disassemble", no_argument, NULL, 'd'},
   {"disassemble-all", no_argument, NULL, 'D'},
+  {"disassembler-options", required_argument, NULL, 'M'},
   {"disassemble-zeroes", no_argument, &disassemble_zeroes, 1},
   {"dynamic-reloc", no_argument, NULL, 'R'},
   {"dynamic-syms", no_argument, NULL, 'T'},
@@ -1564,6 +1569,8 @@ disassemble_data (abfd)
   disasm_info.flavour = bfd_get_flavour (abfd);
   disasm_info.arch = bfd_get_arch (abfd);
   disasm_info.mach = bfd_get_mach (abfd);
+  disasm_info.disassembler_options = disassembler_options;
+  
   if (bfd_big_endian (abfd))
     disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_BIG;
   else if (bfd_little_endian (abfd))
@@ -2694,7 +2701,7 @@ main (argc, argv)
   bfd_init ();
   set_default_bfd_target ();
 
-  while ((c = getopt_long (argc, argv, "pib:m:VCdDlfahrRtTxsSj:wE:",
+  while ((c = getopt_long (argc, argv, "pib:m:M:VCdDlfahrRtTxsSj:wE:",
                           long_options, (int *) 0))
         != EOF)
     {
@@ -2707,6 +2714,9 @@ main (argc, argv)
        case 'm':
          machine = optarg;
          break;
+       case 'M':
+         disassembler_options = optarg;
+         break;
        case 'j':
          only = optarg;
          break;
index fbadf92fdf410f433d0fe6102d6abdeaeedbfc94..d318d969ee4ecd8ba2836134f96c4759fc2403a7 100644 (file)
@@ -1,3 +1,8 @@
+1999-06-14  Nick Clifton  <nickc@cygnus.com>
+
+       * dis-asm.h (arm_toggle_regnames): New prototype.
+       (struct diassemble_info): New field: disassembler_options.
+
 1999-04-11  Richard Henderson  <rth@cygnus.com>
 
        * bfdlink.h (bfd_elf_version_expr): Rename `match' to `pattern'.
index 666ed69015228b8c69c9d9d061239e90ff2f37b7..b42a5ca1dfa308b3c0c962947b3cbbb26611d06f 100644 (file)
@@ -133,6 +133,9 @@ typedef struct disassemble_info {
                                   zero if unknown.  */
   bfd_vma target2;             /* Second target address for dref2 */
 
+  /* Command line options specific to the target disassembler.  */
+  char * disassembler_options;
+
 } disassemble_info;
 
 \f
@@ -181,6 +184,8 @@ extern int print_insn_tic30         PARAMS ((bfd_vma, disassemble_info*));
 extern int print_insn_vax              PARAMS ((bfd_vma, disassemble_info*));
 extern int print_insn_tic80            PARAMS ((bfd_vma, disassemble_info*));
 
+extern int arm_toggle_regnames          PARAMS ((void));
+
 /* Fetch the disassembler for a given BFD, if that support is available.  */
 extern disassembler_ftype disassembler PARAMS ((bfd *));
 
index 777ddea7e075a0ab3df8bae6a6f1d82abe66bce8..09a76dc0714c854060c0dd2bcea4f56c049eb077 100644 (file)
@@ -1,3 +1,22 @@
+1999-06-14  Nick Clifton  <nickc@cygnus.com> & Drew Mosley <dmoseley@cygnus.com>
+
+       * arm-dis.c (arm_regnames): Turn into a pointer to a register
+       name set.
+       (arm_regnames_standard): New variable: Array of ARM register
+       names according to ARM instruction set nomenclature. 
+       (arm_regnames_apcs): New variable: Array of ARM register names
+       according to ARM Procedure Call Standard.
+       (arm_regnames_raw): New variable: Array of ARM register names
+       using just 'r' and the register number.
+       (arm_toggle_regnames): New function: Toggle the chosen register set
+       naming scheme.
+       (parse_disassembler_options): New function: Parse any target
+       disassembler command line options.
+       (print_insn_big_arm): Call parse_disassembler_options if any
+       are defined.
+       (print_insn_little_arm): Call parse_disassembler_options if any
+       are defined.
+
 1999-06-13  Ian Lance Taylor  <ian@zembu.com>
 
        * i386-dis.c (FWAIT_OPCODE): Define.
index 5bc1350eb419084765b210d2a204e813f50e8916..ba03b9baef1cc5301b29d5ae97584d835c5bb85d 100644 (file)
@@ -1,5 +1,5 @@
 /* Instruction printing code for the ARM
-   Copyright (C) 1994, 95, 96, 97, 1998 Free Software Foundation, Inc. 
+   Copyright (C) 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. 
    Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
    Modification by James G. Smith (jsmith@cygnus.co.uk)
 
@@ -35,9 +35,20 @@ static char *arm_conditional[] =
 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
  "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
 
-static char *arm_regnames[] =
+static char *arm_regnames_raw[] =
 {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc"};
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"};
+
+static char *arm_regnames_standard[] =
+{"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc"};
+
+static char *arm_regnames_apcs[] =
+{"a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4",
+ "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc"};
+
+/* Choose which register name set to use.  */
+static char **arm_regnames = arm_regnames_standard;
 
 static char *arm_fp_const[] =
 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
@@ -742,6 +753,45 @@ print_insn_thumb (pc, info, given)
   abort ();
 }
 
+/* Select a different register name set.
+   Returns true if the name set selected is the APCS name set.  */
+int
+arm_toggle_regnames ()
+{
+  if (arm_regnames == arm_regnames_standard)
+    arm_regnames = arm_regnames_apcs;
+  else
+    arm_regnames = arm_regnames_standard;
+
+  return arm_regnames == arm_regnames_apcs;
+}
+
+static void
+parse_disassembler_options (options)
+     char * options;
+{
+  if (options == NULL)
+    return;
+      
+  if (strncmp (options, "reg-names-", 10) == 0)
+    {
+      options += 10;
+      
+      if (strcmp (options, "std") == 0)
+       arm_regnames = arm_regnames_standard;
+      else if (strcmp (options, "apcs") == 0)
+       arm_regnames = arm_regnames_apcs;
+      else if (strcmp (options, "raw") == 0)
+       arm_regnames = arm_regnames_raw;
+      else
+       fprintf (stderr, "Unrecognised register name set: %s\n", options);
+    }
+  else
+    fprintf (stderr, "Unrecognised disassembler option: %s\n", options);
+  
+  return;
+}
+
 /* NOTE: There are no checks in these routines that the relevant number of data bytes exist */
 
 int
@@ -756,6 +806,14 @@ print_insn_big_arm (pc, info)
   elf_symbol_type    *es;
   int                is_thumb;
   
+  if (info->disassembler_options)
+    {
+      parse_disassembler_options (info->disassembler_options);
+      
+      /* To avoid repeated parsing of this option, we remove it here.  */
+      info->disassembler_options = NULL;
+    }
+  
   is_thumb = false;
   if (info->symbols != NULL)
     {
@@ -838,6 +896,14 @@ print_insn_little_arm (pc, info)
   elf_symbol_type    *es;
   int                is_thumb;
 
+  if (info->disassembler_options)
+    {
+      parse_disassembler_options (info->disassembler_options);
+      
+      /* To avoid repeated parsing of this option, we remove it here.  */
+      info->disassembler_options = NULL;
+    }
+  
   is_thumb = false;
   if (info->symbols != NULL)
     {
index 4898b42458d03ca9ab2092a32bfa5e97b6fff7e7..da6d5d5712c5a996bd7c6d064fc52c8684eaeca6 100644 (file)
@@ -245,4 +245,3 @@ disassembler (abfd)
     }
   return disassemble;
 }
-