gas/testsuite/
authorDaniel Jacobowitz <drow@false.org>
Fri, 29 Jan 2010 16:47:55 +0000 (16:47 +0000)
committerDaniel Jacobowitz <drow@false.org>
Fri, 29 Jan 2010 16:47:55 +0000 (16:47 +0000)
* gas/arm/dis-data.d: Update test name.  Do not expect
.word output.
* gas/arm/dis-data2.d, gas/arm/dis-data2.s,
gas/arm/dis-data3.d, gas/arm/dis-data3.s: New tests.

opcodes/
* opcodes/arm-dis.c (struct arm_private_data): New.
(print_insn_coprocessor, print_insn_arm): Update to use struct
arm_private_data.
(is_mapping_symbol, get_map_sym_type): New functions.
(get_sym_code_type): Check the symbol's section.  Do not check
mapping symbols.
(print_insn): Default to disassembling ARM mode code.  Check
for mapping symbols separately from other symbols.  Use
struct arm_private_data.

gas/testsuite/ChangeLog
gas/testsuite/gas/arm/dis-data.d
gas/testsuite/gas/arm/dis-data2.d [new file with mode: 0644]
gas/testsuite/gas/arm/dis-data2.s [new file with mode: 0644]
gas/testsuite/gas/arm/dis-data3.d [new file with mode: 0644]
gas/testsuite/gas/arm/dis-data3.s [new file with mode: 0644]
opcodes/ChangeLog
opcodes/arm-dis.c

index ffd0c49..b525810 100644 (file)
@@ -1,3 +1,10 @@
+2010-01-29  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * gas/arm/dis-data.d: Update test name.  Do not expect
+       .word output.
+       * gas/arm/dis-data2.d, gas/arm/dis-data2.s,
+       gas/arm/dis-data3.d, gas/arm/dis-data3.s: New tests.
+
 2010-01-29  Nick Clifton  <nickc@redhat.com>
 
        PR 11136
index 9715453..40ca770 100644 (file)
@@ -1,10 +1,10 @@
-# name: Data disassembler test
+# name: Data disassembler test (no symbols)
 # skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
 # objdump: -dr --prefix-addresses --show-raw-insn
 
 .*: +file format .*arm.*
 
 Disassembly of section \.text:
-0x00000000 20010000    .word   0x20010000
-0x00000004 000000f9    .word   0x000000f9
-0x00000008 00004cd5    .word   0x00004cd5
+0x00000000 20010000    andcs   r0, r1, r0
+0x00000004 000000f9    strdeq  r0, \[r0\], -r9
+0x00000008 00004cd5    ldrdeq  r4, \[r0\], -r5
diff --git a/gas/testsuite/gas/arm/dis-data2.d b/gas/testsuite/gas/arm/dis-data2.d
new file mode 100644 (file)
index 0000000..ef7bb81
--- /dev/null
@@ -0,0 +1,10 @@
+# name: Data disassembler test (function symbol)
+# skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
+# objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section \.text:
+00000000 <main> 20010000       andcs   r0, r1, r0
+00000004 <main\+0x4> 000000f9  strdeq  r0, \[r0\], -r9
+00000008 <main\+0x8> 00004cd5  ldrdeq  r4, \[r0\], -r5
diff --git a/gas/testsuite/gas/arm/dis-data2.s b/gas/testsuite/gas/arm/dis-data2.s
new file mode 100644 (file)
index 0000000..30eaa67
--- /dev/null
@@ -0,0 +1,8 @@
+.syntax unified
+.type main, %function
+.globl main
+main:
+.word  0x20010000
+.word  0x000000f9
+.word  0x00004cd5
+
diff --git a/gas/testsuite/gas/arm/dis-data3.d b/gas/testsuite/gas/arm/dis-data3.d
new file mode 100644 (file)
index 0000000..e33159b
--- /dev/null
@@ -0,0 +1,11 @@
+# name: Data disassembler test (with mapping symbol)
+# skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
+# objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section \.text:
+00000000 <main> 20010000       .word   0x20010000
+00000004 <main\+0x4> 000000f9  .word   0x000000f9
+00000008 <main\+0x8> 00004cd5  .word   0x00004cd5
+0000000c <main\+0xc> e1a00000  nop                     ; \(mov r0, r0\)
diff --git a/gas/testsuite/gas/arm/dis-data3.s b/gas/testsuite/gas/arm/dis-data3.s
new file mode 100644 (file)
index 0000000..73da9b4
--- /dev/null
@@ -0,0 +1,8 @@
+.syntax unified
+.type main, %function
+.globl main
+main:
+.word  0x20010000
+.word  0x000000f9
+.word  0x00004cd5
+nop
index 875ee2c..7ab07ef 100644 (file)
@@ -1,3 +1,15 @@
+2010-01-29  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * opcodes/arm-dis.c (struct arm_private_data): New.
+       (print_insn_coprocessor, print_insn_arm): Update to use struct
+       arm_private_data.
+       (is_mapping_symbol, get_map_sym_type): New functions.
+       (get_sym_code_type): Check the symbol's section.  Do not check
+       mapping symbols.
+       (print_insn): Default to disassembling ARM mode code.  Check
+       for mapping symbols separately from other symbols.  Use
+       struct arm_private_data.
+
 2010-01-28  H.J. Lu  <hongjiu.lu@intel.com>
 
        * i386-dis.c (EXVexWdqScalar): New.
index 0318d4a..fba3e3b 100644 (file)
 #define NUM_ELEM(a)     (sizeof (a) / sizeof (a)[0])
 #endif
 
+struct arm_private_data
+{
+  /* The features to use when disassembling optional instructions.  */
+  arm_feature_set features;
+
+  /* Whether any mapping symbols are present in the provided symbol
+     table.  -1 if we do not know yet, otherwise 0 or 1.  */
+  int has_mapping_symbols;
+};
+
 struct opcode32
 {
   unsigned long arch;          /* Architecture defining this insn.  */
@@ -1750,7 +1760,8 @@ print_insn_coprocessor (bfd_vma pc,
   fprintf_ftype func = info->fprintf_func;
   unsigned long mask;
   unsigned long value = 0;
-  unsigned long allowed_arches = ((arm_feature_set *) info->private_data)->coproc;
+  struct arm_private_data *private_data = info->private_data;
+  unsigned long allowed_arches = private_data->features.coproc;
   int cond;
 
   for (insn = coprocessor_opcodes; insn->assembler; insn++)
@@ -1776,7 +1787,7 @@ print_insn_coprocessor (bfd_vma pc,
            continue;
 
          case SENTINEL_GENERIC_START:
-           allowed_arches = ((arm_feature_set *) info->private_data)->core;
+           allowed_arches = private_data->features.core;
            continue;
 
          default:
@@ -2843,6 +2854,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
   const struct opcode32 *insn;
   void *stream = info->stream;
   fprintf_ftype func = info->fprintf_func;
+  struct arm_private_data *private_data = info->private_data;
 
   if (print_insn_coprocessor (pc, info, given, FALSE))
     return;
@@ -2855,7 +2867,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
       if ((given & insn->mask) != insn->value)
        continue;
     
-      if ((insn->arch & ((arm_feature_set *) info->private_data)->core) == 0)
+      if ((insn->arch & private_data->features.core) == 0)
        continue;
 
       /* Special case: an instruction with all bits set in the condition field
@@ -3057,7 +3069,7 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
                          /* The p-variants of tst/cmp/cmn/teq are the pre-V6
                             mechanism for setting PSR flag bits.  They are
                             obsolete in V6 onwards.  */
-                         if (((((arm_feature_set *) info->private_data)->core) & ARM_EXT_V6) == 0)
+                         if ((private_data->features.core & ARM_EXT_V6) == 0)
                            func (stream, "p");
                        }
                      break;
@@ -4268,7 +4280,44 @@ find_ifthen_state (bfd_vma pc,
     ifthen_state = 0;
 }
 
-/* Try to infer the code type (Arm or Thumb) from a symbol.
+/* Returns nonzero and sets *MAP_TYPE if the N'th symbol is a
+   mapping symbol.  */
+
+static int
+is_mapping_symbol (struct disassemble_info *info, int n,
+                  enum map_type *map_type)
+{
+  const char *name;
+
+  name = bfd_asymbol_name (info->symtab[n]);
+  if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
+      && (name[2] == 0 || name[2] == '.'))
+    {
+      *map_type = ((name[1] == 'a') ? MAP_ARM
+                  : (name[1] == 't') ? MAP_THUMB
+                  : MAP_DATA);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+/* Try to infer the code type (ARM or Thumb) from a mapping symbol.
+   Returns nonzero if *MAP_TYPE was set.  */
+
+static int
+get_map_sym_type (struct disassemble_info *info,
+                 int n,
+                 enum map_type *map_type)
+{
+  /* If the symbol is in a different section, ignore it.  */
+  if (info->section != NULL && info->section != info->symtab[n]->section)
+    return FALSE;
+
+  return is_mapping_symbol (info, n, map_type);
+}
+
+/* Try to infer the code type (ARM or Thumb) from a non-mapping symbol.
    Returns nonzero if *MAP_TYPE was set.  */
 
 static int
@@ -4278,7 +4327,10 @@ get_sym_code_type (struct disassemble_info *info,
 {
   elf_symbol_type *es;
   unsigned int type;
-  const char *name;
+
+  /* If the symbol is in a different section, ignore it.  */
+  if (info->section != NULL && info->section != info->symtab[n]->section)
+    return FALSE;
 
   es = *(elf_symbol_type **)(info->symtab + n);
   type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
@@ -4290,17 +4342,6 @@ get_sym_code_type (struct disassemble_info *info,
       return TRUE;
     }
 
-  /* Check for mapping symbols.  */
-  name = bfd_asymbol_name (info->symtab[n]);
-  if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
-      && (name[2] == 0 || name[2] == '.'))
-    {
-      *map_type = ((name[1] == 'a') ? MAP_ARM
-                  : (name[1] == 't') ? MAP_THUMB
-                  : MAP_DATA);
-      return TRUE;
-    }
-
   return FALSE;
 }
 
@@ -4355,12 +4396,12 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
   long         given;
   int           status;
   int           is_thumb = FALSE;
-  int           is_data = (bfd_asymbol_flavour (*info->symtab)
-                          == bfd_target_elf_flavour) ? TRUE : FALSE;
+  int           is_data = FALSE;
   int           little_code;
   unsigned int size = 4;
   void         (*printer) (bfd_vma, struct disassemble_info *, long);
   bfd_boolean   found = FALSE;
+  struct arm_private_data *private_data;
 
   if (info->disassembler_options)
     {
@@ -4373,7 +4414,7 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
   /* PR 10288: Control which instructions will be disassembled.  */
   if (info->private_data == NULL)
     {
-      static arm_feature_set features;
+      static struct arm_private_data private;
 
       if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
        /* If the user did not use the -m command line switch then default to
@@ -4399,67 +4440,124 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
       /* Compute the architecture bitmask from the machine number.
         Note: This assumes that the machine number will not change
         during disassembly....  */
-      select_arm_features (info->mach, & features);
+      select_arm_features (info->mach, & private.features);
 
-      info->private_data = & features;
+      private.has_mapping_symbols = -1;
+
+      info->private_data = & private;
     }
-  
+
+  private_data = info->private_data;
+
   /* Decide if our code is going to be little-endian, despite what the
      function argument might say.  */
   little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
 
-  /* First check the full symtab for a mapping symbol, even if there
-     are no usable non-mapping symbols for this address.  */
+  /* For ELF, consult the symbol table to determine what kind of code
+     or data we have.  */
   if (info->symtab_size != 0
       && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
     {
       bfd_vma addr;
-      int n;
+      int n, start;
       int last_sym = -1;
-      enum map_type type = MAP_DATA;
+      enum map_type type = MAP_ARM;
 
-      if (pc <= last_mapping_addr)
-       last_mapping_sym = -1;
-      is_thumb = (last_type == MAP_THUMB);
-      found = FALSE;
       /* Start scanning at the start of the function, or wherever
         we finished last time.  */
-      n = info->symtab_pos + 1;
-      if (n < last_mapping_sym)
-       n = last_mapping_sym;
+      start = info->symtab_pos + 1;
+      if (start < last_mapping_sym)
+       start = last_mapping_sym;
+      found = FALSE;
 
-      /* Scan up to the location being disassembled.  */
-      for (; n < info->symtab_size; n++)
+      /* First, look for mapping symbols.  */
+      if (private_data->has_mapping_symbols != 0)
        {
-         addr = bfd_asymbol_value (info->symtab[n]);
-         if (addr > pc)
-           break;
-         if ((info->section == NULL
-              || info->section == info->symtab[n]->section)
-             && get_sym_code_type (info, n, &type))
+         /* Scan up to the location being disassembled.  */
+         for (n = start; n < info->symtab_size; n++)
+           {
+             addr = bfd_asymbol_value (info->symtab[n]);
+             if (addr > pc)
+               break;
+             if (get_map_sym_type (info, n, &type))
+               {
+                 last_sym = n;
+                 found = TRUE;
+               }
+           }
+
+         if (!found)
+           {
+             /* No mapping symbol found at this address.  Look backwards
+                for a preceeding one.  */
+             for (n = start - 1; n >= 0; n--)
+               {
+                 if (get_map_sym_type (info, n, &type))
+                   {
+                     last_sym = n;
+                     found = TRUE;
+                     break;
+                   }
+               }
+           }
+
+         if (found)
+           private_data->has_mapping_symbols = 1;
+
+         /* No mapping symbols were found.  A leading $d may be
+            omitted for sections which start with data; but for
+            compatibility with legacy and stripped binaries, only
+            assume the leading $d if there is at least one mapping
+            symbol in the file.  */
+         if (!found && private_data->has_mapping_symbols == -1)
            {
-             last_sym = n;
+             /* Look for mapping symbols, in any section.  */
+             for (n = 0; n < info->symtab_size; n++)
+               if (is_mapping_symbol (info, n, &type))
+                 {
+                   private_data->has_mapping_symbols = 1;
+                   break;
+                 }
+             if (private_data->has_mapping_symbols == -1)
+               private_data->has_mapping_symbols = 0;
+           }
+
+         if (!found && private_data->has_mapping_symbols == 1)
+           {
+             type = MAP_DATA;
              found = TRUE;
            }
        }
 
+      /* Next search for function symbols to separate ARM from Thumb
+        in binaries without mapping symbols.  */
       if (!found)
        {
-         n = info->symtab_pos;
-         if (n < last_mapping_sym - 1)
-           n = last_mapping_sym - 1;
-
-         /* No mapping symbol found at this address.  Look backwards
-            for a preceeding one.  */
-         for (; n >= 0; n--)
+         /* Scan up to the location being disassembled.  */
+         for (n = start; n < info->symtab_size; n++)
            {
-             if ((info->section == NULL
-                  || info->section == info->symtab[n]->section)
-                 && get_sym_code_type (info, n, &type))
+             addr = bfd_asymbol_value (info->symtab[n]);
+             if (addr > pc)
+               break;
+             if (get_sym_code_type (info, n, &type))
                {
                  last_sym = n;
                  found = TRUE;
-                 break;
+               }
+           }
+
+         if (!found)
+           {
+             /* No mapping symbol found at this address.  Look backwards
+                for a preceeding one.  */
+             for (n = start - 1; n >= 0; n--)
+               {
+                 if (get_sym_code_type (info, n, &type))
+                   {
+                     last_sym = n;
+                     found = TRUE;
+                     break;
+                   }
                }
            }
        }