Thu Nov 12 19:21:57 1998 Dave Brolley <brolley@cygnus.com>
[deliverable/binutils-gdb.git] / opcodes / arm-dis.c
index 91bcab120a9daa1e9d94179f08ab7bb07541259e..3e4e002f1c2465e63bb7a006439eb6abc0a08a8f 100644 (file)
@@ -1,5 +1,5 @@
 /* Instruction printing code for the ARM
-   Copyright (C) 1994, 95, 96, 1997 Free Software Foundation, Inc. 
+   Copyright (C) 1994, 95, 96, 97, 1998 Free Software Foundation, Inc. 
    Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
    Modification by James G. Smith (jsmith@cygnus.co.uk)
 
@@ -24,6 +24,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "arm-opc.h"
 #include "coff/internal.h"
 #include "libcoff.h"
+#include "opintl.h"
+
+/* FIXME: This shouldn't be done here */
+#include "elf-bfd.h"
+#include "elf/internal.h"
 
 static char *arm_conditional[] =
 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
@@ -308,9 +313,12 @@ print_insn_arm (pc, info, given)
                    case 'C':
                      switch (given & 0x00090000)
                        {
-                       case 0:
+                       default:
                          func (stream, "_???");
                          break;
+                       case 0x90000:
+                         func (stream, "_all");
+                         break;
                        case 0x10000:
                          func (stream, "_ctl");
                          break;
@@ -350,7 +358,7 @@ print_insn_arm (pc, info, given)
                          func (stream, "e");
                          break;
                        default:
-                         func (stream, "<illegal precision>");
+                         func (stream, _("<illegal precision>"));
                          break;
                        }
                      break;
@@ -639,7 +647,11 @@ print_insn_thumb (pc, info, given)
                                       break;
 
                                     case 'a':
-                                      info->print_address_func (((pc + 4) & ~1) + (reg << 2), info);
+                                     /* PC-relative address -- the bottom two
+                                        bits of the address are dropped before
+                                        the calculation.  */
+                                      info->print_address_func
+                                       (((pc + 4) & ~3) + (reg << 2), info);
                                       break;
 
                                     case 'x':
@@ -709,17 +721,30 @@ print_insn_big_arm (pc, info)
   unsigned char      b[4];
   long               given;
   int                status;
-  asymbol *          saved_symbol;
-  coff_symbol_type * cs;
+  coff_symbol_type   *cs;
+  elf_symbol_type    *es;
   int                is_thumb;
   
-  cs = coffsymbol (info->symbol);
-  is_thumb = (cs != NULL) &&
-     (   cs->native->u.syment.n_sclass == C_THUMBEXT
-      || cs->native->u.syment.n_sclass == C_THUMBSTAT
-      || cs->native->u.syment.n_sclass == C_THUMBLABEL
-      || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
-      || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
+  is_thumb = false;
+  if (info->symbols != NULL)
+    {
+    if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
+     {
+       cs = coffsymbol (*info->symbols);
+       is_thumb = (cs->native->u.syment.n_sclass == C_THUMBEXT
+                   || cs->native->u.syment.n_sclass == C_THUMBSTAT
+                   || cs->native->u.syment.n_sclass == C_THUMBLABEL
+                   || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
+                   || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
+  
+     }
+    else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
+     {
+       es = *(elf_symbol_type **)(info->symbols);
+       is_thumb = ELF_ST_TYPE (es->internal_elf_sym.st_info) ==
+        STT_ARM_TFUNC;
+      }
+   }
 
   info->bytes_per_chunk = 4;
   info->display_endian = BFD_ENDIAN_BIG;
@@ -758,8 +783,6 @@ print_insn_big_arm (pc, info)
       given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
     }
 
-  saved_symbol = info->symbol;
-  
   if (is_thumb)
     {
       status = print_insn_thumb (pc, info, given);
@@ -769,8 +792,6 @@ print_insn_big_arm (pc, info)
       status = print_insn_arm (pc, info, given);
     }
 
-  info->symbol = saved_symbol; /* Stop displayed symbols from resetting the stored symbol */
-  
   return status;
 }
 
@@ -782,17 +803,30 @@ print_insn_little_arm (pc, info)
   unsigned char      b[4];
   long               given;
   int                status;
-  asymbol *          saved_symbol;
-  coff_symbol_type * cs;
+  coff_symbol_type   *cs;
+  elf_symbol_type    *es;
   int                is_thumb;
+
+  is_thumb = false;
+  if (info->symbols != NULL)
+    {
+    if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
+     {
+       cs = coffsymbol (*info->symbols);
+       is_thumb = (cs->native->u.syment.n_sclass == C_THUMBEXT
+                   || cs->native->u.syment.n_sclass == C_THUMBSTAT
+                   || cs->native->u.syment.n_sclass == C_THUMBLABEL
+                   || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
+                   || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
   
-  cs = coffsymbol (info->symbol);
-  is_thumb = (cs != NULL) && 
-     (   cs->native->u.syment.n_sclass == C_THUMBEXT
-      || cs->native->u.syment.n_sclass == C_THUMBSTAT
-      || cs->native->u.syment.n_sclass == C_THUMBLABEL
-      || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
-      || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
+     }
+    else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
+     {
+       es = *(elf_symbol_type **)(info->symbols);
+       is_thumb = ELF_ST_TYPE (es->internal_elf_sym.st_info) ==
+        STT_ARM_TFUNC;
+      }
+   }
 
   info->bytes_per_chunk = 4;
   info->display_endian = BFD_ENDIAN_LITTLE;
@@ -813,8 +847,6 @@ print_insn_little_arm (pc, info)
 
   given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
 
-  saved_symbol = info->symbol;
-  
   if (is_thumb)
     {
       status = print_insn_thumb (pc, info, given);
@@ -824,7 +856,5 @@ print_insn_little_arm (pc, info)
       status = print_insn_arm (pc, info, given);
     }
 
-  info->symbol = saved_symbol; /* Stop displayed symbols from resetting the stored symbol */
-
   return status;
 }
This page took 0.025544 seconds and 4 git commands to generate.