opcodes/
authorDaniel Jacobowitz <drow@false.org>
Wed, 22 Nov 2006 17:45:57 +0000 (17:45 +0000)
committerDaniel Jacobowitz <drow@false.org>
Wed, 22 Nov 2006 17:45:57 +0000 (17:45 +0000)
* arm-dis.c (last_is_thumb): Delete.
(enum map_type, last_type): New.
(print_insn_data): New.
(get_sym_code_type): Take MAP_TYPE argument.  Check the type of
the right symbol.  Handle $d.
(print_insn): Check for mapping symbols even without a normal
symbol.  Adjust searching.  If $d is found see how much data
to print.  Handle data.
gas/
* config/tc-arm.h (md_cons_align): Define.
(mapping_state): New prototype.
* config/tc-arm.c (mapping_state): Make global.
gas/testsuite/
* gas/arm/arm7t.d, gas/arm/neon-ldst-rm.d, gas/arm/thumb2_pool.d,
gas/arm/tls.d: Update for $d support.
* gas/arm/mapshort.d, gas/arm/mapshort.s: New test.
* gas/elf/section2.e-armeabi: Update.
* gas/elf/section2.e-armelf: New file.
* gas/elf/elf.exp: Use it.
ld/testsuite/
* ld-arm/mixed-app.d, ld-arm/tls-app.d, ld-arm/tls-lib.d: Update
for $d support.

19 files changed:
gas/ChangeLog
gas/config/tc-arm.c
gas/config/tc-arm.h
gas/testsuite/ChangeLog
gas/testsuite/gas/arm/arm7t.d
gas/testsuite/gas/arm/mapshort.d [new file with mode: 0644]
gas/testsuite/gas/arm/mapshort.s [new file with mode: 0644]
gas/testsuite/gas/arm/neon-ldst-rm.d
gas/testsuite/gas/arm/thumb2_pool.d
gas/testsuite/gas/arm/tls.d
gas/testsuite/gas/elf/elf.exp
gas/testsuite/gas/elf/section2.e-armeabi
gas/testsuite/gas/elf/section2.e-armelf [new file with mode: 0644]
ld/testsuite/ChangeLog
ld/testsuite/ld-arm/mixed-app.d
ld/testsuite/ld-arm/tls-app.d
ld/testsuite/ld-arm/tls-lib.d
opcodes/ChangeLog
opcodes/arm-dis.c

index 543a316a4e8bab6589ee9f4399e44c09371cc12b..503b59d07ce954388f229cd3913f88255f30e50d 100644 (file)
@@ -1,3 +1,9 @@
+2006-11-22  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * config/tc-arm.h (md_cons_align): Define.
+       (mapping_state): New prototype.
+       * config/tc-arm.c (mapping_state): Make global.
+
 2006-11-22  Alan Modra  <amodra@bigpond.net.au>
 
        * config/obj-elf.c (obj_elf_version): Use memcpy rather than strcpy.
index dcc8e8050300598e06a82a5838bab2b0d4fe79a9..f7a3e74f3a44e68383559d74e2dfd72029883af9 100644 (file)
@@ -2282,7 +2282,7 @@ s_unreq (int a ATTRIBUTE_UNUSED)
 
 static enum mstate mapstate = MAP_UNDEFINED;
 
-static void
+void
 mapping_state (enum mstate state)
 {
   symbolS * symbolP;
index 64ebb51bee401ede58efd78713c9ecc777ef7a8b..56ceec4ef3bfb3e9ab2b0fa4ba06f210f01ebf4c 100644 (file)
@@ -192,6 +192,12 @@ extern void arm_md_end (void);
 # define GLOBAL_OFFSET_TABLE_NAME      "_GLOBAL_OFFSET_TABLE_"
 # define TC_SEGMENT_INFO_TYPE          struct arm_segment_info_type
 
+/* This is not really an alignment operation, but it's something we
+   need to do at the same time: whenever we are figuring out the
+   alignment for data, we should check whether a $d symbol is
+   necessary.  */
+# define md_cons_align(nbytes)         mapping_state (MAP_DATA)
+
 enum mstate
 {
   MAP_UNDEFINED = 0, /* Must be zero, for seginfo in new sections.  */
@@ -200,6 +206,8 @@ enum mstate
   MAP_THUMB
 };
 
+void mapping_state (enum mstate);
+
 struct arm_segment_info_type
 {
   enum mstate mapstate;
index 95e184a9406a622d5d24c1fd86a75eb1778c07f7..ca48446461471106eeeb378797ffc3aec8619643 100644 (file)
@@ -1,3 +1,12 @@
+2006-11-22  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * gas/arm/arm7t.d, gas/arm/neon-ldst-rm.d, gas/arm/thumb2_pool.d,
+       gas/arm/tls.d: Update for $d support.
+       * gas/arm/mapshort.d, gas/arm/mapshort.s: New test.
+       * gas/elf/section2.e-armeabi: Update.
+       * gas/elf/section2.e-armelf: New file.
+       * gas/elf/elf.exp: Use it.
+
 2006-11-16  Nathan Sidwell  <nathan@codesourcery.com>
 
        * gas/m68k/all.exp: Add mcf-trap.
index 17e4e9d4fb5ec8c944d47ec8a16eaf5273e6292b..65513885319a47cec9978d8609d563405e400e0d 100644 (file)
@@ -62,7 +62,7 @@ Disassembly of section .text:
 0+d0 <[^>]*> b19100d2 ?        ldrltsb r0, \[r1, r2\]
 0+d4 <[^>]*> e1df00f4 ?        ldrsh   r0, \[pc, #4\]  ; 0+e0 <[^>]*>
 0+d8 <[^>]*> e1df00f4 ?        ldrsh   r0, \[pc, #4\]  ; 0+e4 <[^>]*>
-0+dc <[^>]*> 00000000 ?        andeq   r0, r0, r0
+0+dc <[^>]*> 00000000 ?        .word   0x00000000
 [              ]*dc:.*fred
 0+e0 <[^>]*> 0000c0de ?        .*
 0+e4 <[^>]*> 0000dead ?        .*
diff --git a/gas/testsuite/gas/arm/mapshort.d b/gas/testsuite/gas/arm/mapshort.d
new file mode 100644 (file)
index 0000000..d5b5793
--- /dev/null
@@ -0,0 +1,41 @@
+#objdump: --syms --special-syms -d
+#name: ARM Mapping Symbols for .short
+# This test is only valid on ELF based ports.
+#not-target: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
+
+# Test the generation and use of ARM ELF Mapping Symbols
+
+.*: +file format .*arm.*
+
+SYMBOL TABLE:
+0+00 l    d  .text     00000000 .text
+0+00 l    d  .data     00000000 .data
+0+00 l    d  .bss      00000000 .bss
+0+00 l     F .text     00000000 foo
+0+00 l       .text     00000000 \$a
+0+04 l       .text     00000000 \$t
+0+08 l       .text     00000000 \$d
+0+12 l       .text     00000000 \$t
+0+16 l       .text     00000000 \$d
+0+18 l       .text     00000000 \$a
+0+1c l       .text     00000000 \$d
+0+1f l       .text     00000000 bar
+
+
+Disassembly of section .text:
+
+0+00 <foo>:
+   0:  e1a00000        nop                     \(mov r0,r0\)
+   4:  46c0            nop                     \(mov r8, r8\)
+   6:  46c0            nop                     \(mov r8, r8\)
+   8:  00000002        .word   0x00000002
+   c:  00010001        .word   0x00010001
+  10:  0003            .short  0x0003
+  12:  46c0            nop                     \(mov r8, r8\)
+  14:  46c0            nop                     \(mov r8, r8\)
+  16:  0001            .short  0x0001
+  18:  ebfffff8        bl      0 <foo>
+  1c:  0008            .short  0x0008
+  1e:  09              .byte   0x09
+0+1f <bar>:
+  1f:  0a              .byte   0x0a
diff --git a/gas/testsuite/gas/arm/mapshort.s b/gas/testsuite/gas/arm/mapshort.s
new file mode 100644 (file)
index 0000000..a119447
--- /dev/null
@@ -0,0 +1,21 @@
+       .text
+       .type foo, %function
+foo:
+       .code 32
+       nop
+       .code 16
+       nop
+       nop
+       .long 2
+       .short 1
+       .short 1
+       .short 3
+       nop
+       nop
+       .short 1
+       .code 32
+       bl foo
+       .short 8
+       .byte 9
+bar:
+       .byte 10
index c538fc93d606de504c0660103c62badc5e093556..292d17a6a31ac94a363aa0efa82dd9443f0b2cc5 100644 (file)
@@ -45,7 +45,7 @@ Disassembly of section \.text:
 0[0-9a-f]+ <[^>]+> ed224b08    vstmdb  r2!, {d4-d7}
 0[0-9a-f]+ <[^>]+> ed628b10    vstmdb  r2!, {d24-d31}
 0[0-9a-f]+ <[^>]+> ed223b20    vstmdb  r2!, {d3-d18}
-0[0-9a-f]+ <backward> 000001f4         streqd  r0, \[r0\], -r4
+0[0-9a-f]+ <backward> 000001f4         .word   0x000001f4
 0[0-9a-f]+ <[^>]+> eddf6b0b    vldr    d22, \[pc, #44\]        ; 0[0-9a-f]+ <forward>
 0[0-9a-f]+ <[^>]+> ed935b00    vldr    d5, \[r3\]
 0[0-9a-f]+ <[^>]+> ed135b01    vldr    d5, \[r3, #-4\]
@@ -59,5 +59,5 @@ Disassembly of section \.text:
 0[0-9a-f]+ <[^>]+> ed835b00    vstr    d5, \[r3\]
 0[0-9a-f]+ <[^>]+> ed035b40    vstr    d5, \[r3, #-256\]
 0[0-9a-f]+ <[^>]+> ed835b40    vstr    d5, \[r3, #256\]
-0[0-9a-f]+ <forward> 000002bc  streqh  r0, \[r0\], -ip
+0[0-9a-f]+ <forward> 000002bc  .word   0x000002bc
 0[0-9a-f]+ <[^>]+> ed1f7b11    vldr    d7, \[pc, #-68\]        ; 0[0-9a-f]+ <backward>
index 7bf0c605d5fda2ac63ff0d96a5ec67778ecd3e10..3e3ca59e1eec531c2a2aa2cdfd916ca5f916a0b1 100644 (file)
@@ -11,5 +11,4 @@ Disassembly of section .text:
 0+00c <[^>]+> bf00             nop
 0+00e <[^>]+> f8df 5004        ldr\.w  r5, \[pc, #4\]  ; 00+14 <[^>]+>
 0+012 <[^>]+> 4900             ldr     r1, \[pc, #0\]  \(00+14 <[^>]+>\)
-0+014 <[^>]+> (5678|1234) .*
-0+016 <[^>]+> (1234|5678) .*
+0+014 <[^>]+> 12345678 ?       .word   0x12345678
index 5b41109292cb359a684a237054a76efdb6a924d3..5189dfff01f45974a28797985d1aa3bf02f154fc 100644 (file)
@@ -15,11 +15,11 @@ Disassembly of section .text:
    0:  e1a00000        nop                     \(mov r0,r0\)
    4:  e1a00000        nop                     \(mov r0,r0\)
    8:  e1a0f00e        mov     pc, lr
-   c:  00000000        andeq   r0, r0, r0
+   c:  00000000        .word   0x00000000
                        c: R_ARM_TLS_GD32       a
-  10:  00000004        andeq   r0, r0, r4
+  10:  00000004        .word   0x00000004
                        10: R_ARM_TLS_LDM32     b
-  14:  00000008        andeq   r0, r0, r8
+  14:  00000008        .word   0x00000008
                        14: R_ARM_TLS_IE32      c
-  18:  00000000        andeq   r0, r0, r0
+  18:  00000000        .word   0x00000000
                        18: R_ARM_TLS_LE32      d
index 67ccc5b4eb9a915b46a73385e450f782f82a839b..0d51aa01d5fa231bbcd57ee6103161b638cbd56c 100644 (file)
@@ -54,10 +54,14 @@ if { ([istarget "*-*-*elf*"]
        set target_machine -score
     }
     if { ([istarget "*arm*-*-*"]
-         || [istarget "xscale*-*-*"])
-       && ([istarget "*-*-*eabi"]
-           || [istarget "*-*-symbianelf"])} then {
-       set target_machine -armeabi
+         || [istarget "xscale*-*-*"]) } {
+       
+       if { ([istarget "*-*-*eabi"]
+             || [istarget "*-*-symbianelf"])} then {
+           set target_machine -armeabi
+       } else {
+           set target_machine -armelf
+       }
     }
     run_dump_test "ehopt0"
     run_dump_test "group0a" 
index 84463b1f8b2bea71c0c72ce4ae149812863d9650..13a1525847c4a2fac1d126a860161135bffebe12 100644 (file)
@@ -7,3 +7,4 @@ Symbol table '.symtab' contains 6 entries:
      3: 0+0     0 SECTION LOCAL  DEFAULT    3 
      4: 0+0     0 SECTION LOCAL  DEFAULT    4 
      5: 0+0     0 SECTION LOCAL  DEFAULT    5 
+     6: 0+0     0 NOTYPE  LOCAL  DEFAULT    4 \$d
diff --git a/gas/testsuite/gas/elf/section2.e-armelf b/gas/testsuite/gas/elf/section2.e-armelf
new file mode 100644 (file)
index 0000000..8d2e4ff
--- /dev/null
@@ -0,0 +1,9 @@
+
+Symbol table '.symtab' contains 6 entries:
+   Num:    Value[      ]* Size Type    Bind   Vis      Ndx Name
+     0: 0+0     0 NOTYPE  LOCAL  DEFAULT  UND 
+     1: 0+0     0 SECTION LOCAL  DEFAULT    1 
+     2: 0+0     0 SECTION LOCAL  DEFAULT    2 
+     3: 0+0     0 SECTION LOCAL  DEFAULT    3 
+     4: 0+0     0 SECTION LOCAL  DEFAULT    4 
+     5: 0+0     0 NOTYPE  LOCAL  DEFAULT    4 \$d
index 9b0a20fec909f1d32ab73a48f33dfcf114399a57..1e7f2879f859281d9faa1ffb77b6ac6d9302bf55 100644 (file)
@@ -1,3 +1,8 @@
+2006-11-22  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * ld-arm/mixed-app.d, ld-arm/tls-app.d, ld-arm/tls-lib.d: Update
+       for $d support.
+
 2006-11-21  Jakub Jelinek  <jakub@redhat.com>
 
        * ld-elf/eh5.d: New test.
index dd61caab26c40c8ff37a16691f52c36d7d2579d2..8fa06fc5b35d4bcdd0b3ea4900b16bf8857e505b 100644 (file)
@@ -12,7 +12,8 @@ Disassembly of section .plt:
  .*:   e08fe00e        add     lr, pc, lr
  .*:   e5bef008        ldr     pc, \[lr, #8\]!
  .*:   .*
- .*:   (46c04778       undefined|477846c0      ldrmib  r4, \[r8, -r0, asr #13\]!)
+ .*:   4778            bx      pc
+ .*:   46c0            nop                     \(mov r8, r8\)
  .*:   e28fc6.*        add     ip, pc, #.*     ; 0x.*
  .*:   e28cca.*        add     ip, ip, #.*     ; 0x.*
  .*:   e5bcf.*         ldr     pc, \[ip, #.*\]!
index c1d61abeeaf16536e9df34d20beedd535552450a..fd3d6380087be57a04d96149a8d3b588b59ccd9d 100644 (file)
@@ -10,9 +10,9 @@ Disassembly of section .text:
     8204:      e1a00000        nop                     \(mov r0,r0\)
     8208:      e1a00000        nop                     \(mov r0,r0\)
     820c:      e1a0f00e        mov     pc, lr
-    8210:      000080bc        streqh  r8, \[r0\], -ip
-    8214:      000080b4        streqh  r8, \[r0\], -r4
-    8218:      000080ac        andeq   r8, r0, ip, lsr #1
-    821c:      00000004        andeq   r0, r0, r4
-    8220:      000080c4        andeq   r8, r0, r4, asr #1
-    8224:      00000014        andeq   r0, r0, r4, lsl r0
+    8210:      000080bc        .word   0x000080bc
+    8214:      000080b4        .word   0x000080b4
+    8218:      000080ac        .word   0x000080ac
+    821c:      00000004        .word   0x00000004
+    8220:      000080c4        .word   0x000080c4
+    8224:      00000014        .word   0x00000014
index 76dcfd0c9468077867c4535d9521684ced6c516f..774ac91203f7e85d5a5b47fc749ea9793b483cb1 100644 (file)
@@ -10,6 +10,6 @@ Disassembly of section .text:
  .*:   e1a00000        nop                     \(mov r0,r0\)
  .*:   e1a00000        nop                     \(mov r0,r0\)
  .*:   e1a0f00e        mov     pc, lr
- .*:   00008098        muleq   r0, r8, r0
- .*:   0000808c        andeq   r8, r0, ip, lsl #1
- .*:   00000004        andeq   r0, r0, r4
+ .*:   00008098        .word   0x00008098
+ .*:   0000808c        .word   0x0000808c
+ .*:   00000004        .word   0x00000004
index 9397d42f50320a73ef1f575680fb0136f78916c3..00b0aaf31ac5de91d7240b51d754cac2d44500fc 100644 (file)
@@ -1,3 +1,14 @@
+2006-11-22  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * arm-dis.c (last_is_thumb): Delete.
+       (enum map_type, last_type): New.
+       (print_insn_data): New.
+       (get_sym_code_type): Take MAP_TYPE argument.  Check the type of
+       the right symbol.  Handle $d.
+       (print_insn): Check for mapping symbols even without a normal
+       symbol.  Adjust searching.  If $d is found see how much data
+       to print.  Handle data.
+
 2006-11-16  Nathan Sidwell  <nathan@codesourcery.com>
 
        * m68k-opc.c (m68k_opcodes): Place trap instructions before set
index 7a02e319cfbd1f64dba85c66d2f966922f13f39c..c5342fae02c8987dbd154f75a4ded41cc44ce272 100644 (file)
@@ -1480,8 +1480,14 @@ static unsigned int ifthen_next_state;
 static bfd_vma ifthen_address;
 #define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
 
-/* Cached Thumb state.  */
-int last_is_thumb;
+/* Cached mapping symbol state.  */
+enum map_type {
+  MAP_ARM,
+  MAP_THUMB,
+  MAP_DATA
+};
+
+enum map_type last_type;
 int last_mapping_sym = -1;
 bfd_vma last_mapping_addr = 0;
 
@@ -3711,6 +3717,28 @@ print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
   abort ();
 }
 
+/* Print data bytes on INFO->STREAM.  */
+
+static void
+print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED, struct disassemble_info *info,
+                long given)
+{
+  switch (info->bytes_per_chunk)
+    {
+    case 1:
+      info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
+      break;
+    case 2:
+      info->fprintf_func (info->stream, ".short\t0x%04lx", given);
+      break;
+    case 4:
+      info->fprintf_func (info->stream, ".word\t0x%08lx", given);
+      break;
+    default:
+      abort ();
+    }
+}
+
 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
    being displayed in symbol relative addresses.  */
 
@@ -3865,31 +3893,34 @@ find_ifthen_state (bfd_vma pc, struct disassemble_info *info,
 }
 
 /* Try to infer the code type (Arm or Thumb) from a symbol.
-   Returns nonzero if is_thumb was set.  */
+   Returns nonzero if *MAP_TYPE was set.  */
 
 static int
-get_sym_code_type (struct disassemble_info *info, int n, int *is_thumb)
+get_sym_code_type (struct disassemble_info *info, int n,
+                  enum map_type *map_type)
 {
   elf_symbol_type *es;
   unsigned int type;
   const char *name;
 
-  es = *(elf_symbol_type **)(info->symbols);
+  es = *(elf_symbol_type **)(info->symtab + n);
   type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
 
   /* If the symbol has function type then use that.  */
   if (type == STT_FUNC || type == STT_ARM_TFUNC)
     {
-      *is_thumb = (type == STT_ARM_TFUNC);
+      *map_type = (type == STT_ARM_TFUNC) ? MAP_THUMB : MAP_ARM;
       return TRUE;
     }
 
   /* Check for mapping symbols.  */
   name = bfd_asymbol_name(info->symtab[n]);
-  if (name[0] == '$' && (name[1] == 'a' || name[1] == 't')
+  if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
       && (name[2] == 0 || name[2] == '.'))
     {
-      *is_thumb = (name[1] == 't');
+      *map_type = ((name[1] == 'a') ? MAP_ARM
+                  : (name[1] == 't') ? MAP_THUMB
+                  : MAP_DATA);
       return TRUE;
     }
 
@@ -3905,9 +3936,11 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
   unsigned char b[4];
   long         given;
   int           status;
-  int           is_thumb;
-  int          size;
+  int           is_thumb = FALSE;
+  int           is_data = FALSE;
+  unsigned int size = 4;
   void         (*printer) (bfd_vma, struct disassemble_info *, long);
+  bfd_boolean   found = FALSE;
 
   if (info->disassembler_options)
     {
@@ -3917,9 +3950,89 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
       info->disassembler_options = NULL;
     }
 
-  is_thumb = force_thumb;
+  /* First check the full symtab for a mapping symbol, even if there
+     are no usable non-mapping symbols for this address.  */
+  if (info->symtab != NULL
+      && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
+    {
+      bfd_vma addr;
+      int n;
+      int last_sym = -1;
+      enum map_type type;
+
+      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;
+
+      /* Scan up to the location being disassembled.  */
+      for (; n < info->symtab_size; n++)
+       {
+         addr = bfd_asymbol_value (info->symtab[n]);
+         if (addr > pc)
+           break;
+         if (get_sym_code_type (info, n, &type))
+           {
+             last_sym = n;
+             found = TRUE;
+           }
+       }
+
+      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--)
+           {
+             if (get_sym_code_type (info, n, &type))
+               {
+                 last_sym = n;
+                 found = TRUE;
+                 break;
+               }
+           }
+       }
+
+      last_mapping_sym = last_sym;
+      last_type = type;
+      is_thumb = (last_type == MAP_THUMB);
+      is_data = (last_type == MAP_DATA);
 
-  if (!is_thumb && info->symbols != NULL)
+      /* Look a little bit ahead to see if we should print out
+        two or four bytes of data.  If there's a symbol,
+        mapping or otherwise, after two bytes then don't
+        print more.  */
+      if (is_data)
+       {
+         size = 4 - (pc & 3);
+         for (n = last_sym + 1; n < info->symtab_size; n++)
+           {
+             addr = bfd_asymbol_value (info->symtab[n]);
+             if (addr > pc)
+               {
+                 if (addr - pc < size)
+                   size = addr - pc;
+                 break;
+               }
+           }
+         /* If the next symbol is after three bytes, we need to
+            print only part of the data, so that we can use either
+            .byte or .short.  */
+         if (size == 3)
+           size = (pc & 1) ? 1 : 2;
+       }
+    }
+
+  if (info->symbols != NULL)
     {
       if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
        {
@@ -3932,80 +4045,45 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
                      || 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)
+      else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
+              && !found)
        {
-         bfd_vma addr;
-         int n;
-         int last_sym;
-         bfd_boolean found;
-
-         if (info->symtab)
-           {
-             if (pc <= last_mapping_addr)
-               last_mapping_sym = -1;
-             is_thumb = last_is_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;
-
-             /* Scan up to the location being disassembled.  */
-             for (; n < info->symtab_size; n++)
-               {
-                 addr = bfd_asymbol_value (info->symtab[n]);
-                 if (addr > pc)
-                   break;
-                 if (get_sym_code_type (info, n, &is_thumb))
-                   found = TRUE;
-               }
-
-             last_sym = n;
-             if (!found)
-               {
-                 if (last_mapping_sym == -1)
-                   last_mapping_sym = 0;
-                 else
-                   found = TRUE;
-
-                 /* No mapping symbol found at this address.  Look backwards
-                    for a preceeding one.  */
-                 for (n = info->symtab_pos; n >= last_mapping_sym; n--)
-                   {
-                     if (get_sym_code_type (info, n, &is_thumb))
-                       {
-                         found = TRUE;
-                         break;
-                       }
-                   }
-               }
-
-             last_mapping_sym = last_sym;
-             last_is_thumb = is_thumb;
-           }
-         else
-           found = FALSE;
-
          /* If no mapping symbol has been found then fall back to the type
             of the function symbol.  */
-         if (!found)
-           {
-             elf_symbol_type *  es;
-             unsigned int       type;
+         elf_symbol_type *  es;
+         unsigned int       type;
 
-             es = *(elf_symbol_type **)(info->symbols);
-             type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
+         es = *(elf_symbol_type **)(info->symbols);
+         type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
 
-             is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
-           }
+         is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
        }
     }
 
-  info->display_endian  = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
+  if (force_thumb)
+    is_thumb = TRUE;
+
+  info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
   info->bytes_per_line = 4;
 
-  if (!is_thumb)
+  if (is_data)
+    {
+      int i;
+
+      /* size was already set above.  */
+      info->bytes_per_chunk = size;
+      printer = print_insn_data;
+
+      status = info->read_memory_func (pc, (bfd_byte *)b, size, info);
+      given = 0;
+      if (little)
+       for (i = size - 1; i >= 0; i--)
+         given = b[i] | (given << 8);
+      else
+       for (i = 0; i < (int) size; i++)
+         given = b[i] | (given << 8);
+    }
+  else if (!is_thumb)
     {
       /* In ARM mode endianness is a straightforward issue: the instruction
         is four bytes long and is either ordered 0123 or 3210.  */