This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
patches enable thumb disassembler to correctly dump thumb
- To: binutils at sourceware dot cygnus dot com, tdel at mail dot wrs dot com
- Subject: patches enable thumb disassembler to correctly dump thumb
- From: Thomas de Lellis <tdel at windriver dot com>
- Date: Mon, 24 Jan 2000 20:13:28 -0800
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]
...