public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Patch to force disassemble of Thumb instructions
@ 2000-01-03 12:51 Nick Clifton
  2000-04-01  0:00 ` Nick Clifton
  0 siblings, 1 reply; 2+ messages in thread
From: Nick Clifton @ 2000-01-03 12:51 UTC (permalink / raw)
  To: binutils

Hi Guys,

   I am about to check in the patch below.  It adds a new, ARM
   specific command line switch to the disassembler;
   --disassembler-options=force-thumb which can be used to force the
   disassembler to interpret all instructions as Thumb instructions,
   even if it believes them to be ARM instructions.  This can be
   useful when attempting to disassemble COFF format thumb binaries
   produced by non-GNU toolchains.

Cheers
	Nick

2000-01-03  Nick Clifton  <nickc@cygnus.com>

	* arm-dis.c (streq): New macro.
	(strneq): New macro.
	(force_thumb): ew local variable.
	(parse_disassembler_option): New function: Parse a single, ARM
	specific disassembler command line switch.
	(parse_disassembler_option): Call parse_disassembler_option to
	parse individual command line switches.
	(print_insn_big_arm): Check force_thumb.
	(print_insn_little_arm): Check force_thumb.

Index: opcodes/arm-dis.c
===================================================================
RCS file: /cvs/binutils/binutils/opcodes/arm-dis.c,v
retrieving revision 1.8
diff -p -r1.8 arm-dis.c
*** arm-dis.c	1999/11/16 03:37:02	1.8
--- arm-dis.c	2000/01/03 20:43:55
*************** Foundation, Inc., 59 Temple Place - Suit
*** 32,37 ****
--- 32,44 ----
  #include "elf/internal.h"
  #include "elf/arm.h"
  
+ #ifndef streq
+ #define streq(a,b) (strcmp ((a), (b)) == 0)
+ #endif
+ #ifndef strneq
+ #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
+ #endif
+ 
  static char * arm_conditional[] =
  {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
   "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
*************** static char * arm_regnames_apcs[] =
*** 51,65 ****
  /* 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"};
  
  static char * arm_shift[] = 
  {"lsl", "lsr", "asr", "ror"};
! 
! static int print_insn_arm
!   PARAMS ((bfd_vma, struct disassemble_info *, long));
! 
  static void
  arm_decode_shift (given, func, stream)
       long given;
--- 58,79 ----
  /* Choose which register name set to use.  */
  static char ** arm_regnames = arm_regnames_standard;
  
+ static boolean force_thumb = false;
+ 
  static char * arm_fp_const[] =
  {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
  
  static char * arm_shift[] = 
  {"lsl", "lsr", "asr", "ror"};
! \f
! /* Forward declarations.  */
! static void arm_decode_shift PARAMS ((long, fprintf_ftype, void *));
! static int  print_insn_arm   PARAMS ((bfd_vma, struct disassemble_info *, long));
! static int  print_insn_thumb PARAMS ((bfd_vma, struct disassemble_info *, long));
! static void parse_disassembler_option PARAMS ((char *));
! static void parse_disassembler_options PARAMS ((char *));
! \f
! /* Functions. */
  static void
  arm_decode_shift (given, func, stream)
       long given;
*************** arm_toggle_regnames ()
*** 792,823 ****
  }
  
  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
  print_insn_big_arm (pc, info)
--- 806,868 ----
  }
  
  static void
! parse_disassembler_option (option)
!      char * option;
  {
!   if (option == NULL)
      return;
        
!   if (strneq (option, "reg-names-", 10))
      {
!       option += 10;
        
!       if (streq (option, "std"))
  	arm_regnames = arm_regnames_standard;
!       else if (streq (option, "apcs"))
  	arm_regnames = arm_regnames_apcs;
!       else if (streq (option, "raw"))
  	arm_regnames = arm_regnames_raw;
        else
! 	fprintf (stderr, "Unrecognised register name set: %s\n", option);
      }
+   else if (streq (option, "force-thumb"))
+     force_thumb = 1;
+   else if (streq (option, "no-force-thumb"))
+     force_thumb = 0;
    else
!     fprintf (stderr, "Unrecognised disassembler option: %s\n", option);
    
    return;
  }
+ 
+ static void
+ parse_disassembler_options (options)
+      char * options;
+ {
+   char * space;
+   
+   if (options == NULL)
+     return;
+ 
+   do
+     {
+       space = strchr (options, ' ');
+ 
+       if (space)
+ 	{
+ 	  * space = '\0';
+ 	  parse_disassembler_option (options);
+ 	  * space = ' ';
+ 	  options = space + 1;
+ 	}
+       else
+ 	parse_disassembler_option (options);
+     }
+   while (space);
+ }
  
! /* NOTE: There are no checks in these routines that the relevant number of
!    data bytes exist.  */
  
  int
  print_insn_big_arm (pc, info)
*************** print_insn_big_arm (pc, info)
*** 839,846 ****
        info->disassembler_options = NULL;
      }
    
!   is_thumb = false;
!   if (info->symbols != NULL)
      {
        if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
  	{
--- 884,892 ----
        info->disassembler_options = NULL;
      }
    
!   is_thumb = force_thumb;
!   
!   if (!is_thumb && info->symbols != NULL)
      {
        if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
  	{
*************** print_insn_little_arm (pc, info)
*** 919,928 ****
        /* To avoid repeated parsing of this option, we remove it here.  */
        info->disassembler_options = NULL;
      }
!   
!   is_thumb = false;
    
!   if (info->symbols != NULL)
      {
        if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
  	{
--- 965,974 ----
        /* To avoid repeated parsing of this option, we remove it here.  */
        info->disassembler_options = NULL;
      }
! 
!   is_thumb = force_thumb;
    
!   if (!is_thumb && info->symbols != NULL)
      {
        if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
  	{
*************** print_insn_little_arm (pc, info)
*** 952,960 ****
        status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
        b[3] = b[2] = 0;
      }
    if (status != 0)
      {
!       (*info->memory_error_func) (status, pc, info);
        return -1;
      }
  
--- 998,1007 ----
        status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
        b[3] = b[2] = 0;
      }
+   
    if (status != 0)
      {
!       info->memory_error_func (status, pc, info);
        return -1;
      }


2000-01-03  Nick Clifton  <nickc@cygnus.com>

	* binutils.texi: Document new, ARM specific disassembler
          command line switch "-M force-thumb".

Index: binutils/binutils.texi
===================================================================
RCS file: /cvs/binutils/binutils/binutils/binutils.texi,v
retrieving revision 1.14
diff -p -r1.14 binutils.texi
*** binutils.texi	1999/11/21 11:37:21	1.14
--- binutils.texi	2000/01/03 20:43:55
*************** register 13 called 'sp', register 14 cal
*** 1353,1358 ****
--- 1353,1364 ----
  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.
+ 
+ This option can also be used for ARM architectures to force the
+ disassembler to interpret all instructions as THUMB instructions by
+ using the switch @samp{--disassembler-options=force-thumb}.  This can be
+ useful when attempting to disassemble thumb code produced by other
+ compilers.
  
  @item -p
  @itemx --private-headers

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Patch to force disassemble of Thumb instructions
  2000-01-03 12:51 Patch to force disassemble of Thumb instructions Nick Clifton
@ 2000-04-01  0:00 ` Nick Clifton
  0 siblings, 0 replies; 2+ messages in thread
From: Nick Clifton @ 2000-04-01  0:00 UTC (permalink / raw)
  To: binutils

Hi Guys,

   I am about to check in the patch below.  It adds a new, ARM
   specific command line switch to the disassembler;
   --disassembler-options=force-thumb which can be used to force the
   disassembler to interpret all instructions as Thumb instructions,
   even if it believes them to be ARM instructions.  This can be
   useful when attempting to disassemble COFF format thumb binaries
   produced by non-GNU toolchains.

Cheers
	Nick

2000-01-03  Nick Clifton  <nickc@cygnus.com>

	* arm-dis.c (streq): New macro.
	(strneq): New macro.
	(force_thumb): ew local variable.
	(parse_disassembler_option): New function: Parse a single, ARM
	specific disassembler command line switch.
	(parse_disassembler_option): Call parse_disassembler_option to
	parse individual command line switches.
	(print_insn_big_arm): Check force_thumb.
	(print_insn_little_arm): Check force_thumb.

Index: opcodes/arm-dis.c
===================================================================
RCS file: /cvs/binutils/binutils/opcodes/arm-dis.c,v
retrieving revision 1.8
diff -p -r1.8 arm-dis.c
*** arm-dis.c	1999/11/16 03:37:02	1.8
--- arm-dis.c	2000/01/03 20:43:55
*************** Foundation, Inc., 59 Temple Place - Suit
*** 32,37 ****
--- 32,44 ----
  #include "elf/internal.h"
  #include "elf/arm.h"
  
+ #ifndef streq
+ #define streq(a,b) (strcmp ((a), (b)) == 0)
+ #endif
+ #ifndef strneq
+ #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
+ #endif
+ 
  static char * arm_conditional[] =
  {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
   "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
*************** static char * arm_regnames_apcs[] =
*** 51,65 ****
  /* 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"};
  
  static char * arm_shift[] = 
  {"lsl", "lsr", "asr", "ror"};
! 
! static int print_insn_arm
!   PARAMS ((bfd_vma, struct disassemble_info *, long));
! 
  static void
  arm_decode_shift (given, func, stream)
       long given;
--- 58,79 ----
  /* Choose which register name set to use.  */
  static char ** arm_regnames = arm_regnames_standard;
  
+ static boolean force_thumb = false;
+ 
  static char * arm_fp_const[] =
  {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
  
  static char * arm_shift[] = 
  {"lsl", "lsr", "asr", "ror"};
! \f
! /* Forward declarations.  */
! static void arm_decode_shift PARAMS ((long, fprintf_ftype, void *));
! static int  print_insn_arm   PARAMS ((bfd_vma, struct disassemble_info *, long));
! static int  print_insn_thumb PARAMS ((bfd_vma, struct disassemble_info *, long));
! static void parse_disassembler_option PARAMS ((char *));
! static void parse_disassembler_options PARAMS ((char *));
! \f
! /* Functions. */
  static void
  arm_decode_shift (given, func, stream)
       long given;
*************** arm_toggle_regnames ()
*** 792,823 ****
  }
  
  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
  print_insn_big_arm (pc, info)
--- 806,868 ----
  }
  
  static void
! parse_disassembler_option (option)
!      char * option;
  {
!   if (option == NULL)
      return;
        
!   if (strneq (option, "reg-names-", 10))
      {
!       option += 10;
        
!       if (streq (option, "std"))
  	arm_regnames = arm_regnames_standard;
!       else if (streq (option, "apcs"))
  	arm_regnames = arm_regnames_apcs;
!       else if (streq (option, "raw"))
  	arm_regnames = arm_regnames_raw;
        else
! 	fprintf (stderr, "Unrecognised register name set: %s\n", option);
      }
+   else if (streq (option, "force-thumb"))
+     force_thumb = 1;
+   else if (streq (option, "no-force-thumb"))
+     force_thumb = 0;
    else
!     fprintf (stderr, "Unrecognised disassembler option: %s\n", option);
    
    return;
  }
+ 
+ static void
+ parse_disassembler_options (options)
+      char * options;
+ {
+   char * space;
+   
+   if (options == NULL)
+     return;
+ 
+   do
+     {
+       space = strchr (options, ' ');
+ 
+       if (space)
+ 	{
+ 	  * space = '\0';
+ 	  parse_disassembler_option (options);
+ 	  * space = ' ';
+ 	  options = space + 1;
+ 	}
+       else
+ 	parse_disassembler_option (options);
+     }
+   while (space);
+ }
  
! /* NOTE: There are no checks in these routines that the relevant number of
!    data bytes exist.  */
  
  int
  print_insn_big_arm (pc, info)
*************** print_insn_big_arm (pc, info)
*** 839,846 ****
        info->disassembler_options = NULL;
      }
    
!   is_thumb = false;
!   if (info->symbols != NULL)
      {
        if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
  	{
--- 884,892 ----
        info->disassembler_options = NULL;
      }
    
!   is_thumb = force_thumb;
!   
!   if (!is_thumb && info->symbols != NULL)
      {
        if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
  	{
*************** print_insn_little_arm (pc, info)
*** 919,928 ****
        /* To avoid repeated parsing of this option, we remove it here.  */
        info->disassembler_options = NULL;
      }
!   
!   is_thumb = false;
    
!   if (info->symbols != NULL)
      {
        if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
  	{
--- 965,974 ----
        /* To avoid repeated parsing of this option, we remove it here.  */
        info->disassembler_options = NULL;
      }
! 
!   is_thumb = force_thumb;
    
!   if (!is_thumb && info->symbols != NULL)
      {
        if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
  	{
*************** print_insn_little_arm (pc, info)
*** 952,960 ****
        status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
        b[3] = b[2] = 0;
      }
    if (status != 0)
      {
!       (*info->memory_error_func) (status, pc, info);
        return -1;
      }
  
--- 998,1007 ----
        status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
        b[3] = b[2] = 0;
      }
+   
    if (status != 0)
      {
!       info->memory_error_func (status, pc, info);
        return -1;
      }


2000-01-03  Nick Clifton  <nickc@cygnus.com>

	* binutils.texi: Document new, ARM specific disassembler
          command line switch "-M force-thumb".

Index: binutils/binutils.texi
===================================================================
RCS file: /cvs/binutils/binutils/binutils/binutils.texi,v
retrieving revision 1.14
diff -p -r1.14 binutils.texi
*** binutils.texi	1999/11/21 11:37:21	1.14
--- binutils.texi	2000/01/03 20:43:55
*************** register 13 called 'sp', register 14 cal
*** 1353,1358 ****
--- 1353,1364 ----
  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.
+ 
+ This option can also be used for ARM architectures to force the
+ disassembler to interpret all instructions as THUMB instructions by
+ using the switch @samp{--disassembler-options=force-thumb}.  This can be
+ useful when attempting to disassemble thumb code produced by other
+ compilers.
  
  @item -p
  @itemx --private-headers

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2000-04-01  0:00 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-01-03 12:51 Patch to force disassemble of Thumb instructions Nick Clifton
2000-04-01  0:00 ` Nick Clifton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).