大代码模型下eh_frame段PC32重定位相关技术疑问
关于GCC大代码模型下
.eh_frame段及PC32重定位的问题 示例代码
// sample_header.h extern int num; void func(); // sample_header.cc #include "sample_header.h" int num = 10; void func() { num += 10; }
编译与现象
使用命令 g++ -mcmodel=large -c sample_header.cc -o sample_header.o 编译后,通过 readelf -r sample_header.o 查看重定位信息,发现:
.text段为64位重定位类型,符合大代码模型的预期.rela.eh_frame段存在小代码模型风格的PC32重定位
问题
- 该示例无异常处理代码,为何会存在
.eh_frame段? - 为何
.rela.eh_frame会生成PC32重定位,如何修改?
解答
问题1:.eh_frame段的存在原因
GCC默认生成.eh_frame段,它的作用不局限于C++异常处理,还负责**栈展开(stack unwinding)**相关功能:比如生成函数调用栈回溯、处理函数返回时的栈帧清理,甚至在调试场景中辅助获取调用上下文。即便代码里没有显式的try/catch块,编译器为了提供这些基础的栈管理能力,依然会自动生成该段。
问题2:PC32重定位的成因与解决方法
GCC对.eh_frame段的代码模型处理逻辑是独立的,默认不会跟随-mcmodel=large选项切换到64位重定位,因此依然会生成PC32类型的重定位。
解决方法分两种情况:
- 如果不需要栈展开相关功能,可以添加编译选项
-fno-asynchronous-unwind-tables,禁用异步 unwind 表,编译器将不再生成.eh_frame段,PC32重定位自然消失。 - 如果必须保留栈展开功能,目前GCC没有直接选项让
.eh_frame段使用大代码模型的重定位,只能通过禁用该段来消除PC32重定位问题。
内容的提问来源于stack exchange,提问作者Ricky
相关产品推荐
相关产品推荐

