通过阅读 .hex 和 .map,我如何确定 BL 链接到正确的函数偏移量?

Posted

技术标签:

【中文标题】通过阅读 .hex 和 .map,我如何确定 BL 链接到正确的函数偏移量?【英文标题】:By reading .hex and .map, how can I be sure that a BL links to the right function offset? 【发布时间】:2019-12-24 20:53:26 【问题描述】:

我目前正在做一个“十六进制比较”来了解正在发生的事情。

我知道比较十六进制有时会产生太多需要比较的变化。

只需更改一个函数调用,我就可以在十六进制中进行一些小的更改。 我的嵌入代码包含Foo(5);,我将其替换为Bar(5);(其签名相同),然后替换为Bla(5);

当我比较十六进制文件时,我有以下内容:

绿色部分是CRC。

借助 hex 文件和 map 文件,如何确定 Foo 确实已被 Bar 或 Bla 取代,而不是被其他函数取代?

这是我在 ARMv7-M 架构文档link 中发现的内容。但是即使知道了偏移量,我仍然不知道我是否能从中找出一些东西……如何在机器代码中转录 .map 地址?

在.map中,各自的地址是:

我正在使用 IAR 编译器开发 STM32L4xx(皮质 M4)。

【问题讨论】:

为什么没有呢?您应该能够通过查看映射文件中这些函数的地址来检查,并检查偏移量的差异是否匹配。 它不是代码或至少不是链接代码。例如第一个有,and pc, r3, r6, ror #25,这是一个无意义的指令。也应该称之为“intel hex”而不是 hexdump。您应该输入地址。从您的图片翻译需要很长时间才能获得二进制文件以在值上运行objdump。也提供 relative 部分的源和地图文件会有所帮助, 请提供地图文件中这些地址的地址,Foo, Bar, Bla... 为什么你认为链接器没有完成它的工作? 我确定链接器完成了它的工作,我只是对此感到好奇。 【参考方案1】:

与往常一样,您需要该核心的 arm 架构参考手册(以及技术参考手册)。 cortex-m4 trm 会告诉你它是一个 armv7-m 架构,你就可以得到它。

BL 是两条独立的指令,尽管它通常显示为 32,但它们不必背靠背执行,但必须以正确的顺序执行(你不能在两者之间混淆 lr):

11110xxxxxxxxxxx
11111xxxxxxxxxxx

所以

0xF0E6

00011100110000000000000

0xFC03

00011100110000000000000
           100000000110
00011100110100000000110
00011100110100000000110

000 1110 0110 1000 0000 0110
0x0E6806+4+PC

或者编写一个程序(不处理 H=10 上的符号扩展,因为您没有设置这些位):

#include <stdio.h>
void fun ( unsigned int a, unsigned int b )

    unsigned int ra;
    ra=a&0x7FF;
    ra<<=12;
    ra|=(b&0x7FF)<<1;
    ra&=0xFFFFFFFE;
    ra+=4;
    printf("PC(inst)+0x%08X\n",ra);

int main ( void )

    fun(0xF0E6,0xFC03);
    fun(0xF008,0xFD03);
    fun(0xF0C7,0xFC03);
    return(1);

给予:

PC(inst)+0x000E680A
PC(inst)+0x00008A0A
PC(inst)+0x000C780A

有问题的 bl 指令的地址是什么?作为一个英特尔十六进制文件,它无法从您提供的内容中确定。 (我更喜欢 32 位地址的 srec)。

较旧/最先进的 ARM ARM,armv5 更适合查看这两个指令,但是该文档中有一个错字/错误,拇指版本你没有去掉两个较低的位,这将是 arm 版本那条指令。

.thumb
bl here
nop
bl here
nop
nop
nop
here:



00000000 <here-0x10>:
   0:   f000 f806   bl  10 <here>
   4:   46c0        nop         ; (mov r8, r8)
   6:   f000 f803   bl  10 <here>
   a:   46c0        nop         ; (mov r8, r8)
   c:   46c0        nop         ; (mov r8, r8)
   e:   46c0        nop         ; (mov r8, r8)


PC(inst)+0x00000010
PC(inst)+0x0000000A

请注意,对于 GNU 汇编器,您不能只使用 .word 或 .hword 技巧,您必须使用 .inst.n:

.thumb
bl here
nop
bl here
nop
nop
nop
here:
.inst.n 0xf000
.inst.n 0xf806

00000000 <here-0x10>:
   0:   f000 f806   bl  10 <here>
   4:   46c0        nop         ; (mov r8, r8)
   6:   f000 f803   bl  10 <here>
   a:   46c0        nop         ; (mov r8, r8)
   c:   46c0        nop         ; (mov r8, r8)
   e:   46c0        nop         ; (mov r8, r8)

00000010 <here>:
  10:   f000 f806   bl  20 <here+0x10>

和你的一个人:

.thumb
.inst.n 0xF0E6
.inst.n 0xFC03

00000000 <.text>:
   0:   f0e6 fc03   bl  e680a <.text+0xe680a>

【讨论】:

以上是关于通过阅读 .hex 和 .map,我如何确定 BL 链接到正确的函数偏移量?的主要内容,如果未能解决你的问题,请参考以下文章

Blender 导出插件和 bl_idname

如何更改由背景颜色确定的文本颜色?

在 Swift 中正确地将 -Hex- NSData 形式的 4 个字节读入其正确的数据类型(float 或 int)

如何确定 Hadoop map和reduce的个数

如何将 UIColor 转换为 HEX 并在 NSLog 中显示

在 C 中从 HEX 颜色转换为 RGB 结构