This is the mail archive of the binutils@sourceware.cygnus.com 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]

patches enable thumb disassembler to correctly dump thumb


patches enable thumb disassembler to correctly dump thumb instructions
after thumb labels not declared thumb_func.
The inability of the arm/thumb disassembler to detect labels that
were generated in ".code 16" (.thumb) mode -IF- labels were not
specifically tagged using ".thumb_func" caused objdump to produce
an incorrect disassembly dump listing. (Objdump would incorrectly
use ARM mode for THUMB instructions - see testcase at end).
======================================================================
2000-01-18 Thomas de Lellis <tdel@windriver.com>

        * config/tc-arm.c (armadjust_symtab): If the assembler
        is in '.code 16' (.thumb) mode but the label seen
        in was not declared '.thumb_func' set the ST_INFO type
        to the STT_ARM_16BIT mode.  We detect this flag
        in the disassembler to allow objdump to correctly
        disassemble thumb instructions under labels that
        aren't '.thumb_func' labels.

======================================================================
*** tc-arm.c@@/main/3	Mon Oct  4 13:22:20 1999
--- tc-arm.c	Mon Jan 24 15:53:26 2000
*************** arm_adjust_symtab ()
*** 6827,6840 ****
  
    for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
      {
        if (ARM_IS_THUMB (sym))
          {
  	  if (THUMB_IS_FUNC (sym))
! 	    {
! 	      elf_sym = elf_symbol (symbol_get_bfdsym (sym));
! 	      bind = ELF_ST_BIND (elf_sym);
! 	      elf_sym->internal_elf_sym.st_info = ELF_ST_INFO (bind, STT_ARM_TFUNC);
!             }
           }
       }
  #endif
--- 6827,6842 ----
  
    for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
      {
+       /* If in .code 16 mode.  */
        if (ARM_IS_THUMB (sym))
          {
+ 	  elf_sym = elf_symbol (symbol_get_bfdsym (sym));
+ 	  bind = ELF_ST_BIND (elf_sym);
+ 	  /* If it's a .thumb_func, declare it as so, else tag label as .code 16.  */
  	  if (THUMB_IS_FUNC (sym))
! 	    elf_sym->internal_elf_sym.st_info = ELF_ST_INFO (bind, STT_ARM_TFUNC);
! 	  else
! 	    elf_sym->internal_elf_sym.st_info = ELF_ST_INFO (bind, STT_ARM_16BIT);
           }
       }
  #endif
======================================================================
2000-01-24  Thomas de Lellis  <tdel@wrs.com>

        * elf32-arm.h (bfd_elf32_arm_process_before_allocation)
        Add STT_ARM_16BIT where ever STT_ARM_TFUNC used.

        * elf32-arm.h (elf32_arm_final_link_relocate)
        Add STT_ARM_16BIT where ever STT_ARM_TFUNC used.

        * elf32-arm.h (elf32_arm_find_nearest_line)
        Add STT_ARM_16BIT where ever STT_ARM_TFUNC used.

        * elf32-arm.h (elf32_arm_get_symbol_type)
        If STT_ARM_16BIT mode and not object type
        we return the STT_ARM_16ARM flag.  This is
        because not everthing in a .code 16 block is
        an executed instruction.

======================================================================
*** elf32-arm.h@@/main/5	Wed Jan  5 17:55:10 2000
--- elf32-arm.h	Mon Jan 24 19:49:54 2000
*************** bfd_elf32_arm_process_before_allocation 
*** 712,718 ****
  	         the target of the call. If it is a thumb target, we
  	         insert glue.  */
  
! 	      if (ELF_ST_TYPE(h->type) == STT_ARM_TFUNC)
  		record_arm_to_thumb_glue (link_info, h);
  	      break;
  
--- 712,719 ----
  	         the target of the call. If it is a thumb target, we
  	         insert glue.  */
  
! 	      if ((ELF_ST_TYPE(h->type) == STT_ARM_TFUNC)
! 	       || (ELF_ST_TYPE(h->type) == STT_ARM_16BIT))
  		record_arm_to_thumb_glue (link_info, h);
  	      break;
  
*************** bfd_elf32_arm_process_before_allocation 
*** 721,727 ****
  	         up the target of the call. If it is not a thumb
                   target, we insert glue.  */
  
! 	      if (ELF_ST_TYPE (h->type) != STT_ARM_TFUNC)
  		record_thumb_to_arm_glue (link_info, h);
  	      break;
  
--- 722,729 ----
  	         up the target of the call. If it is not a thumb
                   target, we insert glue.  */
  
! 	      if ((ELF_ST_TYPE (h->type) != STT_ARM_TFUNC)
! 	       && (ELF_ST_TYPE (h->type) != STT_ARM_16BIT))
  		record_thumb_to_arm_glue (link_info, h);
  	      break;
  
*************** elf32_arm_final_link_relocate (howto, in
*** 1191,1197 ****
  	  /* Arm B/BL instruction */
  
  	  /* Check for arm calling thumb function.  */
! 	  if (sym_flags == STT_ARM_TFUNC)
  	    {
  	      elf32_arm_to_thumb_stub (info, sym_name, input_bfd, output_bfd,
  				       input_section, hit_data, sym_sec, rel->r_offset,
--- 1193,1200 ----
  	  /* Arm B/BL instruction */
  
  	  /* Check for arm calling thumb function.  */
! 	  if ((sym_flags == STT_ARM_TFUNC)
! 	   || (sym_flags == STT_ARM_16BIT))
  	    {
  	      elf32_arm_to_thumb_stub (info, sym_name, input_bfd, output_bfd,
  				       input_section, hit_data, sym_sec, rel->r_offset,
*************** elf32_arm_final_link_relocate (howto, in
*** 1268,1274 ****
  
  	case R_ARM_ABS32:
  	  value += addend;
! 	  if (sym_flags == STT_ARM_TFUNC)
  	    value |= 1;
  	  break;
  
--- 1271,1278 ----
  
  	case R_ARM_ABS32:
  	  value += addend;
! 	  if ((sym_flags == STT_ARM_TFUNC)
! 	   || (sym_flags == STT_ARM_16BIT))
  	    value |= 1;
  	  break;
  
*************** elf32_arm_final_link_relocate (howto, in
*** 1360,1366 ****
          /* If it is not a call to thumb, assume call to arm.
  	   If it is a call relative to a section name, then it is not a
  	   function call at all, but rather a long jump.  */
! 	if (sym_flags != STT_ARM_TFUNC && sym_flags != STT_SECTION)
  	  {
  	    if (elf32_thumb_to_arm_stub
  		(info, sym_name, input_bfd, output_bfd, input_section,
--- 1364,1372 ----
          /* If it is not a call to thumb, assume call to arm.
  	   If it is a call relative to a section name, then it is not a
  	   function call at all, but rather a long jump.  */
! 	if ((sym_flags != STT_ARM_TFUNC)
! 	 && (sym_flags != STT_ARM_16BIT)
! 	 && (sym_flags != STT_SECTION))
  	  {
  	    if (elf32_thumb_to_arm_stub
  		(info, sym_name, input_bfd, output_bfd, input_section,
*************** elf32_arm_get_symbol_type (elf_sym, type
*** 2140,2149 ****
       Elf_Internal_Sym * elf_sym;
       int type;
  {
!   if (ELF_ST_TYPE (elf_sym->st_info) == STT_ARM_TFUNC)
!     return ELF_ST_TYPE (elf_sym->st_info);
!   else
!     return type;
  }
  
  static asection *
--- 2146,2167 ----
       Elf_Internal_Sym * elf_sym;
       int type;
  {
!   switch (ELF_ST_TYPE (elf_sym->st_info))
!     {
!     case STT_ARM_TFUNC:
!       return ELF_ST_TYPE (elf_sym->st_info);
!       break;
!     case STT_ARM_16BIT:
!       /* If type not object, return the ARM_16BIT flag.
! 	 We keep 'object' to allow us to dump the 'O' flag
! 	 in objdump symbols listings since not everything
! 	 in a .code 16 block is necessarily an instruction.  */
!       if (type != STT_OBJECT)
! 	return ELF_ST_TYPE (elf_sym->st_info);
!       break;
!     }
! 
!   return type;
  }
  
  static asection *
*************** elf32_arm_check_relocs (abfd, info, sec,
*** 2481,2487 ****
  
  /* Find the nearest line to a particular section and offset, for error
     reporting.   This code is a duplicate of the code in elf.c, except
!    that it also accepts STT_ARM_TFUNC as a symbol that names a function. */
  
  static boolean
  elf32_arm_find_nearest_line
--- 2499,2505 ----
  
  /* Find the nearest line to a particular section and offset, for error
     reporting.   This code is a duplicate of the code in elf.c, except
!    that it also accepts STT_ARM_* as a symbol that names a function. */
  
  static boolean
  elf32_arm_find_nearest_line
*************** elf32_arm_find_nearest_line
*** 2540,2545 ****
--- 2558,2564 ----
  	case STT_NOTYPE:
  	case STT_FUNC:
  	case STT_ARM_TFUNC:
+ 	case STT_ARM_16BIT:
  	  if (q->symbol.section == section
  	      && q->symbol.value >= low_func
  	      && q->symbol.value <= offset)
======================================================================
2000-01-24  Thomas de Lellis  <tdel@windriver.com>

        * arm-dis.c (printf_insn_big_arm): Detect STT_ARM_16BIT
        flag.  Instructs disassembler to correctly disassemble
        thumb instructions which don't reside under labels
        that have specifically been tagged '.thumb_func' in
        gas.
        
        * arm-dis.c (printf_insn_little_arm): Ditto.

======================================================================
*** arm-dis.c@@/main/3	Mon Oct  4 14:39:32 1999
--- arm-dis.c	Mon Jan 24 17:56:26 2000
*************** print_insn_big_arm (pc, info)
*** 845,852 ****
        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;
  	}
      }
  
--- 844,852 ----
        else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
  	{
  	  es = *(elf_symbol_type **)(info->symbols);
! 	  /* Thumb is either a .thumb_func label or any label in .code 16 mode.  */
! 	  is_thumb = (ELF_ST_TYPE (es->internal_elf_sym.st_info) == STT_ARM_TFUNC)
! 	          || (ELF_ST_TYPE (es->internal_elf_sym.st_info) == STT_ARM_16BIT);
  	}
      }
  
*************** print_insn_little_arm (pc, info)
*** 927,934 ****
        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;
  	}
      }
    
--- 927,935 ----
        else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
  	{
  	  es = *(elf_symbol_type **)(info->symbols);
! 	  /* Thumb is either a .thumb_func label or any label in .code 16 mode.  */
! 	  is_thumb = (ELF_ST_TYPE (es->internal_elf_sym.st_info) == STT_ARM_TFUNC)
! 	          || (ELF_ST_TYPE (es->internal_elf_sym.st_info) == STT_ARM_16BIT);
  	}
      }
    
======================================================================
2000-01-24  Thomas de Lellis  <tdel@windriver.com>

        * arm.h: Define STT_ARM_16BIT flag.  Denotes
        label was defined in '.code 16' (.thumb) block
        but was not declared '.thumb_func'.  Used mainly
        by opcodes/arm-dis.c to instruct disassembler to
        correctly disassemble thumb instructions under
        non-.thumb_func labels.  Note: STT_HIPROC was
        redefined for this.  (Maybe reuse STT_LOOS instead?)

======================================================================
*** arm.h@@/main/2	Mon Oct  4 14:43:06 1999
--- arm.h	Mon Jan 24 15:42:59 2000
***************
*** 42,48 ****
  #define F_SOFT_FLOAT	   EF_SOFT_FLOAT
  
  /* Additional symbol types for Thumb */
! #define STT_ARM_TFUNC     0xd
  
  /* ARM-specific values for sh_flags */
  #define SHF_ENTRYSECT      0x10000000   /* Section contains an entry point */
--- 42,49 ----
  #define F_SOFT_FLOAT	   EF_SOFT_FLOAT
  
  /* Additional symbol types for Thumb */
! #define STT_ARM_TFUNC      STT_LOPROC   /* Label declared .thumb_func and in .code 16 block.  */
! #define STT_ARM_16BIT      STT_HIPROC   /* Label not declared .thumb_func and in .code 16 block.  */
  
  /* ARM-specific values for sh_flags */
  #define SHF_ENTRYSECT      0x10000000   /* Section contains an entry point */
======================================================================

TESTCASE

>cat aa.s
		.code   32
	        .balign 4
armFunc:
	        mov     r0, #0
	        bx      lr

	.type	armLabel,object
armLabel:
		.long	0
armfunc2:
		nop
		nop

	        .code   16
	        .balign 4
	        .thumb_func
thumbFunc1:
	        NOP
	        NOP
thumbLabel1:
	        BX      lr

	        .balign 4
	        .thumb_func
thumbFunc2:
	        LDR     r0, ptrTPtr
	        LDR     r0, [r0]
	        BX      r0
thumbLabel2:
	        LDR     r0, ptrAPtr
	        LDR     r0, [r0]
	        BX      r0

		.balign 4
ptrTPtr:	.long   tPtr
ptrTPtr2:	.long   tPtr2
ptrAPtr:	.long   aPtr
tPtr:	        .long   thumbFunc1
tPtr2:	        .long   thumbLabel1
aPtr:	        .long   armFunc

sPtr:		.long	string
string:		.string	"hello"

	        .balign 2
		.long	tPtr
		.long	aPtr
		.long	thumbFunc1
		.long	thumbLabel1
		.long	armFunc
		.long	sPtr
thumbLabel3:
		nop
		nop
		nop
	.type thumbLabel4,object
thumbLabel4:
		.long	4
	.type thumbLabel5,function
thumbLabel5:
		nop
	.type thumbLabel6,function
	.thumb_func
thumbLabel6:
		nop
	.type a,object
a:		.long	e
	.type b,object
b:		.long	f
	.type c,object
c:		.long	g
	.type d,object
d:		.long	h
	.type a,object
e:		.long	thumbLabel3
	.type b,object
f:		.long	thumbLabel4
	.type c,object
g:		.long	thumbLabel5
	.type d,object
h:		.long	thumbLabel6

		.data
	.type xxx,function
xxx:		.long	0
	.type yyy,object
yyy:		.long	1
zzz:		.long	2

	.code	32
		.data
	.type xxx2,function
xxx2:		.long	0
	.type yyy2,object
yyy2:		.long	1
zzz2:		.long	2


FAIL ======================================================================


> ./test
+ asthumb -o aa.o aa.s 
+ ldthumb -o a.o aa.o 
ldthumb: warning: cannot find entry symbol _start; defaulting to 00008000
+ objdumpthumb -d a.o 

a.o:     file format elf32-littlearm

Disassembly of section .text:

00008000 <armFunc>:
    8000:       e3a00000        mov     r0, #0  ; 0x0
    8004:       e12fff1e        bx      lr

00008008 <armLabel>:
    8008:       00000000                                ....

0000800c <armfunc2>:
    800c:       e1a00000        nop                     (mov r0,r0)
    8010:       e1a00000        nop                     (mov r0,r0)

00008014 <thumbFunc1>:
    8014:       46c0            46c0    nop                     (mov r8,r8)
    8016:       46c0            46c0    nop                     (mov r8,r8)

00008018 <thumbLabel1>:
    8018:       00004770        andeq   r4, r0, r0, ror r7

0000801c <thumbFunc2>:
    801c:       4802            4802    ldr     r0, [pc, #8]    (8028 <ptrTPtr>)
    801e:       6800            6800    ldr     r0, [r0, #0]
    8020:       4700            4700    bx      r0

00008022 <thumbLabel2>:
    8022:       68004803        stmvsda r0, {r0, r1, r11, lr}
    8026:       80344700        eorhis  r4, r4, r0, lsl #14

00008028 <ptrTPtr>:
    8028:       00008034        andeq   r8, r0, r4, lsr r0

0000802c <ptrTPtr2>:
    802c:       00008038        andeq   r8, r0, r8, lsr r0

00008030 <ptrAPtr>:
    8030:       0000803c        andeq   r8, r0, r12, lsr r0

00008034 <tPtr>:
    8034:       00008015        andeq   r8, r0, r5, lsl r0

00008038 <tPtr2>:
    8038:       00008018        andeq   r8, r0, r8, lsl r0

0000803c <aPtr>:
    803c:       00008000        andeq   r8, r0, r0

00008040 <sPtr>:
    8040:       00008044        andeq   r8, r0, r4, asr #32

00008044 <string>:
    8044:       6c6c6568        stcvsl  5, cr6, [r12], -#416
    8048:       8034006f        eorhis  r0, r4, pc, rrx
    804c:       803c0000        eorhis  r0, r12, r0
    8050:       80150000        andhis  r0, r5, r0
    8054:       80180000        andhis  r0, r8, r0
    8058:       80000000        andhi   r0, r0, r0
    805c:       80400000        subhi   r0, r0, r0
        ...

00008062 <thumbLabel3>:
    8062:       46c046c0        strmib  r4, [r0], r0, asr #13
    8066:       000446c0        andeq   r4, r4, r0, asr #13

00008068 <thumbLabel4>:
    8068:       00000004                                ....

0000806c <thumbLabel5>:
    806c:       46c046c0        strmib  r4, [r0], r0, asr #13

0000806e <thumbLabel6>:
    806e:       46c0            46c0    nop                     (mov r8,r8)

00008070 <a>:
    8070:       8080 0000                                   ....

00008074 <b>:
    8074:       8084 0000                                   ....

00008078 <c>:
    8078:       8088 0000                                   ....

0000807c <d>:
    807c:       808c 0000                                   ....

00008080 <e>:
    8080:       00008062        andeq   r8, r0, r2, rrx

00008084 <f>:
    8084:       00008068        andeq   r8, r0, r8, rrx

00008088 <g>:
    8088:       0000806c        andeq   r8, r0, r12, rrx

0000808c <h>:
    808c:       0000806f        andeq   r8, r0, pc, rrx


PASS ======================================================================


> ./test
+ asthumb -o aa.o aa.s 
+ ldthumb -o a.o aa.o 
ldthumb: warning: cannot find entry symbol _start; defaulting to 00008000
+ objdumpthumb -d a.o 

a.o:     file format elf32-littlearm

Disassembly of section .text:

00008000 <armFunc>:
    8000:       e3a00000        mov     r0, #0  ; 0x0
    8004:       e12fff1e        bx      lr

00008008 <armLabel>:
    8008:       00000000                                ....

0000800c <armfunc2>:
    800c:       e1a00000        nop                     (mov r0,r0)
    8010:       e1a00000        nop                     (mov r0,r0)

00008014 <thumbFunc1>:
    8014:       46c0            nop                     (mov r8,r8)
    8016:       46c0            nop                     (mov r8,r8)

00008018 <thumbLabel1>:
    8018:       4770            bx      lr
        ...

0000801c <thumbFunc2>:
    801c:       4802            ldr     r0, [pc, #8]    (8028 <ptrTPtr>)
    801e:       6800            ldr     r0, [r0, #0]
    8020:       4700            bx      r0

00008022 <thumbLabel2>:
    8022:       4803            ldr     r0, [pc, #12]   (8030 <ptrAPtr>)
    8024:       6800            ldr     r0, [r0, #0]
    8026:       4700            bx      r0

00008028 <ptrTPtr>:
    8028:       8034            strh    r4, [r6, #0]
        ...

0000802c <ptrTPtr2>:
    802c:       8038            strh    r0, [r7, #0]
        ...

00008030 <ptrAPtr>:
    8030:       803c            strh    r4, [r7, #0]
        ...

00008034 <tPtr>:
    8034:       8015            strh    r5, [r2, #0]
        ...

00008038 <tPtr2>:
    8038:       8018            strh    r0, [r3, #0]
        ...

0000803c <aPtr>:
    803c:       8000            strh    r0, [r0, #0]
        ...

00008040 <sPtr>:
    8040:       8044            strh    r4, [r0, #2]
        ...

00008044 <string>:
    8044:       6568            str     r0, [r5, #84]
    8046:       6c6c            ldr     r4, [r5, #68]
    8048:       006f            lsl     r7, r5, #1
    804a:       8034            strh    r4, [r6, #0]
    804c:       0000            lsl     r0, r0, #0
    804e:       803c            strh    r4, [r7, #0]
    8050:       0000            lsl     r0, r0, #0
    8052:       8015            strh    r5, [r2, #0]
    8054:       0000            lsl     r0, r0, #0
    8056:       8018            strh    r0, [r3, #0]
    8058:       0000            lsl     r0, r0, #0
    805a:       8000            strh    r0, [r0, #0]
    805c:       0000            lsl     r0, r0, #0
    805e:       8040            strh    r0, [r0, #2]
        ...

00008062 <thumbLabel3>:
    8062:       46c0            nop                     (mov r8,r8)
    8064:       46c0            nop                     (mov r8,r8)
    8066:       46c0            nop                     (mov r8,r8)

00008068 <thumbLabel4>:
    8068:       0004 0000                                   ....

0000806c <thumbLabel5>:
    806c:       46c0            nop                     (mov r8,r8)

0000806e <thumbLabel6>:
    806e:       46c0            nop                     (mov r8,r8)

00008070 <a>:
    8070:       8080 0000                                   ....

00008074 <b>:
    8074:       8084 0000                                   ....

00008078 <c>:
    8078:       8088 0000                                   ....

0000807c <d>:
    807c:       808c 0000                                   ....

00008080 <e>:
    8080:       8062            strh    r2, [r4, #2]
        ...

00008084 <f>:
    8084:       8068            strh    r0, [r5, #2]
        ...

00008088 <g>:
    8088:       806c            strh    r4, [r5, #2]
        ...

0000808c <h>:
    808c:       806f            strh    r7, [r5, #2]
        ...

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