链接过程主要包括了地址和空间分配(AddressandStorage)、符号决议(SymbolResolution)、和重定位(Relocation)
AI时代,有人焦虑失业,有人偷偷变强,不写代码不烧脑~
相关语录
-
程序源代码被编译以后主要分成两种段:程序指令和程序数据。代码段属于程序指令,而数据段和.bss段属于程序数据。
-
实际上在动态链接器的自举代码中,除了不可以使用全局变量和静态变量之外,甚至不能调用函数,即动态链接器本身的函数也不能调用。这是为什么呢?其实我们在前面分析地址无关代码时已经提到过,实际上使用PIC模式编译的共享对象,对于模块内部的函数调用也是采用外部函数调用一样的方式,即使用GOT/PLT的方式,所以在GOT/PLT没有被重定位之前,自举代码不可以使用任何全局变量,也不可以调用函数。
-
这样看起来第一个模块内部调用或跳转很容易解决,但实际上这种方式还有一定的问题,这里存在一个名作共享对象“全局符号介入”问题。
-
重定位所做的就是给程序中每个这样的绝对地址引用的位置“打补丁”,使它们指向正确的地址。
-
我们在全局变量获函数之前加上__attribute__((section(name)))属性就可以把相应的变量或函数放到以name作为段名的段中。
-
由于可能存在的全局符号介入的问题,foo函数对于bar的调用不能够采用第一类模块调用的方法,因为一旦bar函数由于全局符号介入被其他模块中的同名函数覆盖,那么foo如果采用相对地址调用的话,那么这个相对地址就需要重定位,这由于共享对象的地址无关性矛盾。所以对于bar()函数的调用,编译器只能选择第三种,即当作模块外部符号处理。
-
可以使用volatile关键字来试图阻止过度优化,volatile基本可以做到两件事情:1、阻止编译器为了提高速度将一个变量缓存到寄存器内而不写回。2、阻止编译器调整操作volatile变量的指令顺序。
-
所以对于bar()函数的调用,编译器只能选择第三种,即当作模块的外部符号处理。...即使用static关键字定义bar函数,这种情况下,编译器要确定bar()函数不会其他模块覆盖,就可以使用第一类的方法,即模块内部调用指令。
-
作者写的是:规则3:如果一个符号在所有目标文件中都是弱符号,那么选择其中占用空间最大的一个。比如目标文件A定义全局变量global为int型,占4个字节;目标文件B定义B定义global为double型,占8个字节,那么目标文集A和B链接后,符号global占8个字节。
-
既然每个编译器都能将源代码编译成目标文件,那么有没有不同编译器编译出来的目标文件是不能够相互链接的呢?有没有可能将MSCV编译出来的目标文件和GCC编译出来的目标文件连接到一起,形成一个可执行文件呢?
-
双赢者把生活看作一个合作的舞台,而不是一个角斗场。一般人看事情多用二分法:非强即弱,非胜即败。其实世界之大,人人都有足够的立足空间,他人之得不必就视为自己之失。人际交往的六种模式双赢不是什么技巧,而是人际交往的哲学,是六个交往模式之一,这六个模式分别是:◎利人利己(双赢)◎损人利己(赢/输)◎舍己为人(输/赢)◎两败俱伤(输/输)◎独善其身(赢)◎好聚好散(无交易)“我认输,你赢了。”“就这样吧,

