2017-09-01 114 views
3

我对的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命令添加一个体系结构选项吗?

+1

有objcopy把方法可以做到这一点,但你需要一个固定长度的指令集,没有的Thumb2大拇指(虽然GNU,可能无法正常工作),手臂没有拇指,MIPS 32位只(不包括16位指令),而不是86 ,而不是其他许多人。 –

回答

3

一个小实验......

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指令现在是正确的。

祝你好运。

+0

您使用哪个objdump选项来显示.inst.n行? – joeforker

+0

这些是在这种情况下手工创建的,您可以编写一个读取二进制文件并创建一个类似文件的工具。 –

+0

注意,我证明了,即使我说,这是一个拇指指令inst.n当我把的Thumb2扩展在那里,而不是一个32位inst.w两个16位inst.n拆装想通了,这是一个的Thumb2。 .. –

相关问题