ARM $d mapping symbol support for objdump

Daniel Jacobowitz drow@false.org
Wed Nov 22 17:02:00 GMT 2006


On Wed, Nov 15, 2006 at 06:06:19PM +0000, Richard Earnshaw wrote:
> Incidentally, the assembler should probably have a .iword directive so
> that we can create an entry in the code section that doesn't get marked
> as $d.

Like so?  No docs yet; I'm not sure if this is sufficient, since
there's no way to specify ARM-ness or Thumb-ness.  We can't use .iword
versus .ishort, in the land of Thumb-2.  Should there be a matching
.ishort?

Or I can just commit this without the .iword changes.

-- 
Daniel Jacobowitz
CodeSourcery

2006-11-22  Daniel Jacobowitz  <dan@codesourcery.com>

	* opcodes/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-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.
	(s_arm_elf_cons): Handle .iword.
	(md_pseudo_table): Add .iword.

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-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.

Index: gas/config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.300
diff -u -p -r1.300 tc-arm.c
--- gas/config/tc-arm.c	14 Nov 2006 12:21:13 -0000	1.300
+++ gas/config/tc-arm.c	22 Nov 2006 16:58:01 -0000
@@ -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;
@@ -2870,6 +2870,10 @@ static void flush_pending_unwind (void);
 
 /* Directives: Data.  */
 
+/* Handle an expression for NBYTES worth of data.  If NBYTES < 0, do
+   not mark this with a data mapping symbol; emit -NBYTES worth
+   of data.  */
+
 static void
 s_arm_elf_cons (int nbytes)
 {
@@ -2885,11 +2889,15 @@ s_arm_elf_cons (int nbytes)
       return;
     }
 
-#ifdef md_cons_align
-  md_cons_align (nbytes);
-#endif
+  /* We don't call md_cons_align here, because we only handle mapping
+     symbols there, and we take special care of mapping symbols here
+     for .iword.  */
+
+  if (nbytes > 0)
+    mapping_state (MAP_DATA);
+  else
+    nbytes = - nbytes;
 
-  mapping_state (MAP_DATA);
   do
     {
       int reloc;
@@ -3948,6 +3956,7 @@ const pseudo_typeS md_pseudo_table[] =
   { "object_arch", s_arm_object_arch,	0 },
   { "fpu",	   s_arm_fpu,	  0 },
 #ifdef OBJ_ELF
+  { "iword",	   s_arm_elf_cons, -4 },
   { "word",	   s_arm_elf_cons, 4 },
   { "long",	   s_arm_elf_cons, 4 },
   { "rel31",	   s_arm_rel31,	  0 },
Index: gas/config/tc-arm.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.h,v
retrieving revision 1.41
diff -u -p -r1.41 tc-arm.h
--- gas/config/tc-arm.h	11 Sep 2006 02:32:50 -0000	1.41
+++ gas/config/tc-arm.h	22 Nov 2006 16:58:01 -0000
@@ -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: gas/testsuite/gas/arm/arm7t.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/arm7t.d,v
retrieving revision 1.12
diff -u -p -r1.12 arm7t.d
--- gas/testsuite/gas/arm/arm7t.d	8 Oct 2005 17:07:16 -0000	1.12
+++ gas/testsuite/gas/arm/arm7t.d	22 Nov 2006 16:58:01 -0000
@@ -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 ?	.*
Index: gas/testsuite/gas/arm/mapshort.d
===================================================================
RCS file: gas/testsuite/gas/arm/mapshort.d
diff -N gas/testsuite/gas/arm/mapshort.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/mapshort.d	22 Nov 2006 16:58:01 -0000
@@ -0,0 +1,42 @@
+#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+20 l       .text	00000000 \$d
+0+23 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:	00000000 	andeq	r0, r0, r0
+  20:	0008      	.short	0x0008
+  22:	09          	.byte	0x09
+0+23 <bar>:
+  23:	0a          	.byte	0x0a
Index: gas/testsuite/gas/arm/mapshort.s
===================================================================
RCS file: gas/testsuite/gas/arm/mapshort.s
diff -N gas/testsuite/gas/arm/mapshort.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/mapshort.s	22 Nov 2006 16:58:01 -0000
@@ -0,0 +1,22 @@
+	.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
+	.iword 0
+	.short 8
+	.byte 9
+bar:
+	.byte 10
Index: gas/testsuite/gas/arm/neon-ldst-rm.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/neon-ldst-rm.d,v
retrieving revision 1.2
diff -u -p -r1.2 neon-ldst-rm.d
--- gas/testsuite/gas/arm/neon-ldst-rm.d	26 Apr 2006 15:42:17 -0000	1.2
+++ gas/testsuite/gas/arm/neon-ldst-rm.d	22 Nov 2006 16:58:01 -0000
@@ -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: gas/testsuite/gas/arm/thumb2_pool.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/thumb2_pool.d,v
retrieving revision 1.2
diff -u -p -r1.2 thumb2_pool.d
--- gas/testsuite/gas/arm/thumb2_pool.d	7 Apr 2006 15:03:45 -0000	1.2
+++ gas/testsuite/gas/arm/thumb2_pool.d	22 Nov 2006 16:58:01 -0000
@@ -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: gas/testsuite/gas/arm/tls.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/tls.d,v
retrieving revision 1.3
diff -u -p -r1.3 tls.d
--- gas/testsuite/gas/arm/tls.d	4 Jul 2005 14:55:52 -0000	1.3
+++ gas/testsuite/gas/arm/tls.d	22 Nov 2006 16:58:01 -0000
@@ -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: gas/testsuite/gas/elf/elf.exp
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/elf/elf.exp,v
retrieving revision 1.33
diff -u -p -r1.33 elf.exp
--- gas/testsuite/gas/elf/elf.exp	15 Nov 2006 15:59:26 -0000	1.33
+++ gas/testsuite/gas/elf/elf.exp	22 Nov 2006 16:58:01 -0000
@@ -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: gas/testsuite/gas/elf/section2.e-armeabi
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/elf/section2.e-armeabi,v
retrieving revision 1.1
diff -u -p -r1.1 section2.e-armeabi
--- gas/testsuite/gas/elf/section2.e-armeabi	19 Oct 2005 00:43:59 -0000	1.1
+++ gas/testsuite/gas/elf/section2.e-armeabi	22 Nov 2006 16:58:01 -0000
@@ -7,3 +7,4 @@ Symbol table '.symtab' contains 6 entrie
      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
Index: gas/testsuite/gas/elf/section2.e-armelf
===================================================================
RCS file: gas/testsuite/gas/elf/section2.e-armelf
diff -N gas/testsuite/gas/elf/section2.e-armelf
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/elf/section2.e-armelf	22 Nov 2006 16:58:01 -0000
@@ -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: ld/testsuite/ld-arm/mixed-app.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/mixed-app.d,v
retrieving revision 1.6
diff -u -p -r1.6 mixed-app.d
--- ld/testsuite/ld-arm/mixed-app.d	13 Nov 2006 21:18:36 -0000	1.6
+++ ld/testsuite/ld-arm/mixed-app.d	22 Nov 2006 16:58:02 -0000
@@ -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: ld/testsuite/ld-arm/tls-app.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/tls-app.d,v
retrieving revision 1.4
diff -u -p -r1.4 tls-app.d
--- ld/testsuite/ld-arm/tls-app.d	13 Nov 2006 21:18:36 -0000	1.4
+++ ld/testsuite/ld-arm/tls-app.d	22 Nov 2006 16:58:02 -0000
@@ -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: ld/testsuite/ld-arm/tls-lib.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/tls-lib.d,v
retrieving revision 1.4
diff -u -p -r1.4 tls-lib.d
--- ld/testsuite/ld-arm/tls-lib.d	8 Aug 2005 15:52:54 -0000	1.4
+++ ld/testsuite/ld-arm/tls-lib.d	22 Nov 2006 16:58:02 -0000
@@ -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: opcodes/arm-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/arm-dis.c,v
retrieving revision 1.73
diff -u -p -r1.73 arm-dis.c
--- opcodes/arm-dis.c	31 Oct 2006 20:21:57 -0000	1.73
+++ opcodes/arm-dis.c	22 Nov 2006 16:58:05 -0000
@@ -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 d
   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 di
 }
 
 /* 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 disassemb
   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 disassemb
       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);
+
+      /* 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 (!is_thumb && info->symbols != NULL)
+  if (info->symbols != NULL)
     {
       if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
 	{
@@ -3932,80 +4045,45 @@ print_insn (bfd_vma pc, struct disassemb
 		      || 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.  */



More information about the Binutils mailing list