This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Make ARM BE8 disassembly work


This patch fixes disassembly of ARM's BE8 file format, a version of ELF which is basically big-endian, but the code is stored little-endian. We can continue to use the mapping symbol machinery to get intra-section code/data distinctions right, this patch merely adds flags indicating when code endianness differs from overall endianness. The test case is actually in the linker testsuite; I verified this by building i386-darwin x arm-eabi and running make check in ld. OK to commit?

Stan

include/
   * dis-asm.h (struct disassemble_info): Add endian_code field.

opcodes/
   * dis-init.c (init_disassemble_info): Init endian_code field.
   * arm-dis.c (print_insn): Disassemble code according to
   setting of endian_code.
   (print_insn_big_arm): Detect when BE8 extension flag has been set.

ld/testsuite:
   * ld-arm/arm-elf.exp: Use objdump -d for arm-be8 test.
   * ld-arm/arm-be8.d: Change to test disassembly.


Index: include/dis-asm.h
===================================================================
RCS file: /cvs/src/src/include/dis-asm.h,v
retrieving revision 1.69
diff -u -p -r1.69 dis-asm.h
--- include/dis-asm.h	10 Apr 2008 13:36:43 -0000	1.69
+++ include/dis-asm.h	30 Jun 2008 21:38:31 -0000
@@ -76,6 +76,8 @@ typedef struct disassemble_info
   unsigned long mach;
   /* Endianness (for bi-endian cpus).  Mono-endian cpus can ignore this.  */
   enum bfd_endian endian;
+  /* Endianness of code, for mixed-endian situations such as ARM BE8.  */
+  enum bfd_endian endian_code;
   /* An arch/mach-specific bitmask of selected instruction subsets, mainly
      for processors with run-time-switchable instruction sets.  The default,
      zero, means that there is no constraint.  CGEN-based opcodes ports
Index: opcodes/arm-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/arm-dis.c,v
retrieving revision 1.88
diff -u -p -r1.88 arm-dis.c
--- opcodes/arm-dis.c	7 Nov 2007 14:40:40 -0000	1.88
+++ opcodes/arm-dis.c	30 Jun 2008 21:38:31 -0000
@@ -3974,6 +3974,7 @@ print_insn (bfd_vma pc, struct disassemb
   int           status;
   int           is_thumb = FALSE;
   int           is_data = FALSE;
+  int           little_code;
   unsigned int	size = 4;
   void	 	(*printer) (bfd_vma, struct disassemble_info *, long);
   bfd_boolean   found = FALSE;
@@ -3986,6 +3987,10 @@ print_insn (bfd_vma pc, struct disassemb
       info->disassembler_options = NULL;
     }
 
+  /* 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.  */
   if (info->symtab != NULL
@@ -4131,7 +4136,7 @@ print_insn (bfd_vma pc, struct disassemb
       size = 4;
 
       status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
-      if (little)
+      if (little_code)
 	given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
       else
 	given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
@@ -4147,7 +4152,7 @@ print_insn (bfd_vma pc, struct disassemb
       size = 2;
 
       status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
-      if (little)
+      if (little_code)
 	given = (b[0]) | (b[1] << 8);
       else
 	given = (b[1]) | (b[0] << 8);
@@ -4161,7 +4166,7 @@ print_insn (bfd_vma pc, struct disassemb
 	      || (given & 0xF800) == 0xE800)
 	    {
 	      status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info);
-	      if (little)
+	      if (little_code)
 		given = (b[0]) | (b[1] << 8) | (given << 16);
 	      else
 		given = (b[1]) | (b[0] << 8) | (given << 16);
@@ -4172,7 +4177,7 @@ print_insn (bfd_vma pc, struct disassemb
 	}
 
       if (ifthen_address != pc)
-	find_ifthen_state(pc, info, little);
+	find_ifthen_state(pc, info, little_code);
 
       if (ifthen_state)
 	{
@@ -4210,6 +4215,12 @@ print_insn (bfd_vma pc, struct disassemb
 int
 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
 {
+  /* Detect BE8-ness and record it in the disassembler info.  */
+  if (info->flavour == bfd_target_elf_flavour
+      && info->section != NULL
+      && (elf_elfheader (info->section->owner)->e_flags & EF_ARM_BE8))
+    info->endian_code = BFD_ENDIAN_LITTLE;
+
   return print_insn (pc, info, FALSE);
 }
 
Index: opcodes/dis-init.c
===================================================================
RCS file: /cvs/src/src/opcodes/dis-init.c,v
retrieving revision 1.4
diff -u -p -r1.4 dis-init.c
--- opcodes/dis-init.c	5 Jul 2007 09:49:00 -0000	1.4
+++ opcodes/dis-init.c	30 Jun 2008 21:38:31 -0000
@@ -32,6 +32,7 @@ init_disassemble_info (struct disassembl
   info->flavour = bfd_target_unknown_flavour;
   info->arch = bfd_arch_unknown;
   info->endian = BFD_ENDIAN_UNKNOWN;
+  info->endian_code = info->endian;
   info->octets_per_byte = 1;
   info->fprintf_func = fprintf_func;
   info->stream = stream;
Index: ld/testsuite/ld-arm/arm-be8.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/arm-be8.d,v
retrieving revision 1.1
diff -u -p -r1.1 arm-be8.d
--- ld/testsuite/ld-arm/arm-be8.d	15 May 2006 19:57:35 -0000	1.1
+++ ld/testsuite/ld-arm/arm-be8.d	30 Jun 2008 21:38:31 -0000
@@ -1,8 +1,16 @@
 
 .*:     file format.*
 
-Contents of section .text:
- 8000 0000a0e3 1eff2fe1 c0467047 fff7fcff .*
- 8010 12345678                            .*
-# Ignore .ARM.attributes section
-#...
+Disassembly of section .text:
+
+00008000 <arm>:
+    8000:	0000a0e3 	mov	r0, #0	; 0x0
+    8004:	1eff2fe1 	bx	lr
+
+00008008 <thumb>:
+    8008:	c046      	nop			\(mov r8, r8\)
+    800a:	7047      	bx	lr
+    800c:	fff7 fcff 	bl	8008 <thumb>
+
+00008010 <data>:
+    8010:	12345678 	.word	0x12345678
Index: ld/testsuite/ld-arm/arm-elf.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/arm-elf.exp,v
retrieving revision 1.38
diff -u -p -r1.38 arm-elf.exp
--- ld/testsuite/ld-arm/arm-elf.exp	28 May 2008 15:38:36 -0000	1.38
+++ ld/testsuite/ld-arm/arm-elf.exp	30 Jun 2008 21:38:31 -0000
@@ -144,7 +144,7 @@ set armelftests {
      {{objdump -dw arm-movwt.d}}
      "arm-movwt"}
     {"BE8 Mapping Symbols" "-static -T arm.ld -EB --be8" "-EB" {arm-be8.s}
-     {{objdump -s arm-be8.d}}
+     {{objdump -d arm-be8.d}}
      "arm-be8"}
     {"Using Thumb lib by another lib" "-shared tmpdir/mixed-lib.so" "" {use-thumb-lib.s}
      {{readelf -Ds use-thumb-lib.sym}}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]