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

Does linker do relocation for functions that are referenced but not actually called in the program?

有人告诉我:

如果您的程序引用了库中的 10 个函数但调用了其中的 0 个,则延迟绑定与立即绑定的区别是 0 次查找与 10 次查找。如果您的程序引用了库中的 100 个函数,但只调用了其中的 10 个,则差异是 10 对 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生成的,让我们linkmain.cmylibrary.so进入名为[=16=的可执行文件], 所以根据引用的文本, func_lib 被引用但没有被程序调用,没有惰性绑定,有一个查找(我认为查找意味着由 linker 执行的重定位) func_lib

但我使用 readelf 检查了 prog.rel.text 中没有条目,prog 的任何部分中都没有 func_lib 的条目,因为该程序甚至不调用 func_main,这意味着 linker 不会对 func_lib?

进行任何查找/重定位

声明未引用任何内容。函数声明所做的只是告诉编译器如何处理 func_libs 参数和 return 值(如果它被调用);如果未调用该函数,则该信息无关紧要。 (大多数标准库通常都是这种情况。)

要有引用,您实际上必须以某种方式使用该符号——例如,包含一个调用 func_lib 的函数。 (函数本身是否从未被调用并不重要,只要它具有外部链接并因此可以从其他翻译单元调用即可。)