Linux内核 – 为什么System.map中的函数地址是实时看到的地址之前的一个字节?

在linux内核源代码中,在tasklet_action代码中添加了以下行:

 printk("tasklet_action = %p\n" , *tasklet_action); printk("tasklet_action = %p\n" , &tasklet_action); printk("tasklet_action = %p\n" , tasklet_action); 

在输出中我得到:

 tasklet_action = c03441a1 tasklet_action = c03441a1 tasklet_action = c03441a1 

但在system.map文件中search时, tasklet_action地址位于c03441a0因此存在1个字节的偏移量。

  • 为什么我有这个抵消?
  • 它总是一个字节的偏移量?

我的猜测是,你在ARM 模式下运行在ARM 模式下 ,或者在其他一些使用函数指针底部的体系结构上指出运行模式。

如果是这样的话,答案就是你的函数真的位于system.map的地址中

您在运行时获得的值是位置和模式

在这些类型的体系结构中,指令总是必须是2或4字节对齐的,这将使最低位始终为零。 当架构增长一个额外的模式时,设计师利用“浪费”位来编码模式。 这很聪明,但令人困惑,而不仅仅是为了你:许多软件,比如调试器,在第一次发明的时候就以许多讨厌的方式出现了。

这个概念对于习惯于随机对齐的可变长度指令的x86程序员来说尤其令人困惑。