美文网首页
MachO与重定位符号表的探究

MachO与重定位符号表的探究

作者: qinghan | 来源:发表于2021-05-04 16:09 被阅读0次

    概述

    本篇文章主要是模拟app编译生成MachO过程,在这个过程中我们会了解.o文件、以及重定位符号表、再MachO中系统是如何调用函数的。在这个过程中操作会比较多,但是每一步我都会详细讲解。

    探究

    Macho 代码段

    第一步:新建一个test.m文件,里面只有一个main函数,如下图,进入文件所在目录,然后再终端输入 clang test.m -o test , 实际上test就是一个可执行的最终产物

    第一步.png
    通过objdump --macho -d test可以查看test的的代码段:
    第二步.png
    第二步:我们在test.m 里面添加test1test2两个函数,让后重复上面的操作,如下图:
    第三步.png
    第四步.png
    我们发现machO的代码段也多出对应的函数,并且在顺序也是按照文件声明函数的顺序来排列的。其实地址我们可以看出pagezero + offset,举例:100003f80 = 10000000 + 3f80
    总结:实际macho的代码段存储的就是 虚拟地址+代码指令
    目标文件

    我们知道在编译过程中,我们的.m会先生成中间文件.o,最后把.o文件链接到一起,生成我们的可执行文件machO。
    clang -c test.m -o test生成.o文件

    第四步.png
    • 我们可以看一下.o文件的代码段和最终的可执行文件的代码段不一样(.o文件的前面是序号,而不是虚拟地址),我的理解是这个时候的.o文件还不是最终的产物,只有合并到一起的时候,才能确定在macho的最终位置。
    • 我们在看test1函数的调用,e8 00 00 00 00 其中e8表示调用的意思后面的00 00 00 00实际上是占位的偏移量,这个时候还没有分配。只有再等链接完成后才会给值。
    • 实际上编译的时候所有的这些等待被分配值都会放在一张表里面,我们叫做重定位符号表,可以用下面的命令查看objcdump --macho --reloc test.o
      第五步.png
      如上图,我们可以看到test1test2都在重定位符号表里面
    函数调用

    我们在代码里面在main里面调用了test1,但是再底层是如何查找到test1的地址的呢?

    第六步.png
    如上图所:c5 ff ff ff由于ios是小端模式实际上这个偏移量的值是0xffffffc5这是一个负数,并且是一个补码,那么他的原码
    应该取反加1,得到0x3b ,然后0x10003fab+(-0x3b)=0x10003f70,可以得出0x100003f70正好是test1虚拟地址。

    总结:重定位符号表实际上生成.o文件的时候会生成,最后生成可执行文件会生成一个大的符号表,也就是会合并所有.o文件的重定位表,同时会再占位符填写对应的偏移量的值。

    相关文章

      网友评论

          本文标题:MachO与重定位符号表的探究

          本文链接:https://www.haomeiwen.com/subject/xmycdltx.html