静态变量的重定位 #
还有一个比较特殊的是 static_var 变量。我们可以从 Sym. Name 里找到其余变量的符号,但 static_var 的符号没有出现,只有一个.data 的符号。
这是因为 static_var 变量本身是一个静态变量,只在本编译单元内可见,不会对外进行暴露,所以它是根据本编译单元的.data 段的地址来进行重定位。也就是说,static_var 的最终地址就是本编译单元的.data 段的最终地址。所以,它的重定义方法与 extern_var 等符号的重定位方法是一样的,区别仅仅在于它的符号被隐藏了。如下图所示:
你可能会有疑问,既然静态函数可以在编译的时候确定相对偏移,那为什么静态变量做不到这一点呢?
这是因为静态变量的位置是在 data 段,而对静态函数的访问是在 text 段。对应 text 段内部的偏移可以保证在链接的过程中不发生改变,但由于 text 段和 data 段分属不同的段,在链接的时候大概率会进行重新排布,所以它和引用它的地方之间的相对位置就发生变化了。所以静态变量的地址就需要链接器来进行重定位了。