GCC 的 -fno-plt 选项
Caution
由 gemini-2.5-pro-exp-03-25 生成。
gcc 的 -fno-plt
是什么含义?
-fno-plt
是 GCC 编译器的一个选项,它与程序如何处理函数调用相关,特别是对共享库函数的调用。
作用和含义
-fno-plt
选项禁用 PLT(Procedure Linkage Table,过程链接表)的使用。具体来说:
- PLT 的工作原理:
- 在标准的动态链接中,对外部函数的调用通过 PLT 和 GOT(Global Offset Table,全局偏移表)间接进行
- PLT 包含一小段代码,负责在第一次调用函数时解析其实际地址,并将该地址缓存在 GOT 中
- 后续对同一函数的调用可以直接使用 GOT 中缓存的地址
- 禁用 PLT 的效果:
- 使用
-fno-plt
后,编译器会为每次外部函数调用生成直接的代码 - 函数地址会在程序加载时由动态链接器解析,而不是在第一次调用时解析
- 所有对外部函数的调用将直接通过 GOT 进行
- 使用
使用场景
这个选项主要在以下场景中使用:
- 性能优化:
- 消除 PLT 的查找和间接跳转开销
- 对于频繁调用共享库函数的程序可能会有性能提升
- 在 PIE(Position Independent Executable)中:
- 在使用
-fPIE
构建的可执行文件中,-fno-plt
可以减少代码大小和提高性能
- 在使用
- 安全增强:
- 在某些安全敏感的应用中,移除 PLT 可以减少某些类型的攻击面
- 特别是与 GOT 劫持相关的攻击
潜在缺点
使用 -fno-plt
也有一些潜在的缺点:
- 可能增加程序大小:对于调用许多外部函数的程序来说,可能会增加代码大小(其实并不是很明显)
- 影响动态链接器的延迟绑定优化:PLT 允许延迟绑定,只有在实际需要时才解析函数地址
这个选项通常与其他性能或安全相关的编译选项一起使用,如 -fPIC
、-fPIE
或各种安全加固选项。