如何将二进制固件转储转换为.elf进行汇编语言调试?
我对的ARM Cortex M A二进制固件映像,我知道应该在0x20000000加载。我想将它转换为可用于使用gdb进行组件级调试的格式,我假设它转换为.elf。但是我一直无法弄清楚如何为自己添加足够的元数据。这是我到目前为止所尝试的。如何将二进制固件转储转换为.elf进行汇编语言调试?
arm-none-eabi-objcopy -I binary -O elf32-littlearm --set-section-flags \
.data=alloc,contents,load,readonly \
--change-section-address .data=0x20000000 efr32.bin efr32.elf
efr32.elf: file format elf32-little
efr32.elf
architecture: UNKNOWN!, flags 0x00000010:
HAS_SYMS
start address 0x00000000
Sections:
Idx Name Size VMA LMA File off Algn
0 .data 00000168 20000000 20000000 00000034 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
SYMBOL TABLE:
20000000 l d .data 00000000 .data
20000000 g .data 00000000 _binary_efr32_bin_start
20000168 g .data 00000000 _binary_efr32_bin_end
00000168 g *ABS* 00000000 _binary_efr32_bin_size
我是否需要将二进制文件转换为.o并编写简单的链接器脚本?我应该向objcopy命令添加一个体系结构选项吗?
一个小实验......
58: 480a ldr r0, [pc, #40] ; (84 <spi_write_byte+0x38>)
5a: bf08 it eq
5c: 4809 ldreq r0, [pc, #36] ; (84 <spi_write_byte+0x38>)
5e: f04f 01ff mov.w r1, #255 ; 0xff
你没有那当然,但你可以阅读二进制,并用它做这个:
.thumb
.globl _start
_start:
.inst.n 0x480a
.inst.n 0xbf08
.inst.n 0x4809
.inst.n 0xf04f
.inst.n 0x01ff
然后看看会发生什么。
arm-none-eabi-as test.s -o test.o
arm-none-eabi-ld -Ttext=0x58 test.o -o test.elf
arm-none-eabi-objdump -D test.elf
test.elf: file format elf32-littlearm
Disassembly of section .text:
00000058 <_start>:
58: 480a ldr r0, [pc, #40] ; (84 <_start+0x2c>)
5a: bf08 it eq
5c: 4809 ldreq r0, [pc, #36] ; (84 <_start+0x2c>)
5e: f04f 01ff mov.w r1, #255 ; 0xff
但现实是它不会工作......如果这二进制有任何的Thumb2扩展它不是去上班,你不能拆开线性可变长度的指令。你必须按照执行顺序处理它们。因此,要做到这一点正确,您必须编写通过执行顺序代码散步,确定就可以计算出指令的dissassembler,它们标记为指示...
80: d1e8 bne.n 54 <spi_write_byte+0x8>
82: bd70 pop {r4, r5, r6, pc}
84: 40005200
88: F7FF4000
8c: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr}
90: 4887 ldr r0, [pc, #540] ; (2b0 <notmain+0x224>)
.thumb
.globl _start
_start:
.inst.n 0xd1e8
.inst.n 0xbd70
.inst.n 0x5200
.inst.n 0x4000
.inst.n 0x4000
.inst.n 0xF7FF
.inst.n 0xe92d
.inst.n 0x41f0
.inst.n 0x4887
80: d1e8 bne.n 54 <_start-0x2c>
82: bd70 pop {r4, r5, r6, pc}
84: 5200 strh r0, [r0, r0]
86: 4000 ands r0, r0
88: 4000 ands r0, r0
8a: f7ff e92d ; <UNDEFINED> instruction: 0xf7ffe92d
8e: 41f0 rors r0, r6
90: 4887 ldr r0, [pc, #540] ; (2b0 <_start+0x230>)
将恢复,并打破和恢复等等......
,而不是你写的是通过代码走反汇编(犯规一定要拆机汇编语言,但足以走路的代码和递归一切可能的分支路径)。所有未确定为指令的数据标记为指令
.thumb
.globl _start
_start:
.inst.n 0xd1e8
.inst.n 0xbd70
.word 0x40005200
.word 0xF7FF4000
.inst.n 0xe92d
.inst.n 0x41f0
.inst.n 0x4887
00000080 <_start>:
80: d1e8 bne.n 54 <_start-0x2c>
82: bd70 pop {r4, r5, r6, pc}
84: 40005200 andmi r5, r0, r0, lsl #4
88: f7ff4000 ; <UNDEFINED> instruction: 0xf7ff4000
8c: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr}
90: 4887 ldr r0, [pc, #540] ; (2b0 <_start+0x230>)
我们的stmdb指令现在是正确的。
祝你好运。
您使用哪个objdump选项来显示.inst.n行? – joeforker
这些是在这种情况下手工创建的,您可以编写一个读取二进制文件并创建一个类似文件的工具。 –
注意,我证明了,即使我说,这是一个拇指指令inst.n当我把的Thumb2扩展在那里,而不是一个32位inst.w两个16位inst.n拆装想通了,这是一个的Thumb2。 .. –
有objcopy把方法可以做到这一点,但你需要一个固定长度的指令集,没有的Thumb2大拇指(虽然GNU,可能无法正常工作),手臂没有拇指,MIPS 32位只(不包括16位指令),而不是86 ,而不是其他许多人。 –