链接器是否会对程序中引用但未实际调用的函数进行重定位?

问题描述

有人告诉我:

如果您的程序在库中引用了10个函数,但是调用了0个函数,则延迟绑定与立即绑定的区别是0 vs 10查找。如果您的程序引用了库中的100个函数,但仅调用了10个,则相差10 vs 100查找。

下面是我的代码和理解:

main.c

// this program references func_lib but doesn't call func_main

void func_lib();

void func_main()
{
     func_lib();
}

int main()
{
   return 0;
}

mylibrary.c

void func_lib()
{
   ...
}

,并基于mylibrary.so生成一个共享库mylibrary.c,让我们将main.cmylibrary.so链接到名为prog的可执行文件中,因此根据引用文本func_lib被引用但未被程序调用,没有延迟绑定,func_lib

一个查找(我认为查找是指由链接器执行的重定位)。

但是我使用prog检查了readelf.rel.text中没有条目,func_lib的任何部分中都没有prog的条目,因为该程序甚至没有调用func_main,这意味着链接器不会为func_lib做任何查找/重定位吗?

解决方法

声明不引用任何内容。函数声明的全部作用是告诉编译器如何处理func_lib的参数并在调用时返回值。如果不调用该函数,则该信息无关紧要。 (大多数标准库通常都是这种情况。)

要获得参考,实际上您必须以某种方式使用该符号-例如,包括一个调用func_lib的函数。 (只要函数本身具有外部链接,因此可以从其他翻译单元进行调用,则是否调用该函数本身并不重要。)