Linux下GCC编译ELF文件函数名被截断,如何保留长符号?
GCC 4.8.5编译后ELF符号被截断,如何保留完整长函数名?
问题场景
在Linux系统使用GCC 4.8.5(版本标识:gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44))编译C文件时,通过readelf工具查看符号信息,发现长函数名被截断至25字符。以下是测试代码及操作过程:
测试代码
#include <stdlib.h> #include <stdio.h> #include <stdint.h> void verly_long_function_xjsakdghajkshdlasjkldashjkldhasjklfdsjkhfsdjkhfsdjklhdsjkl_v1(uint32_t val) { int i = 0; for (i = 0 ; i < val; i++) { printf("%d\n", i); } } void verly_long_function_xjsakdghajkshdlasjkldashjkldhasjklfdsjkhfsdjkhfsdjklhdsjkl_v2(uint32_t val) { int i = 0; for (i = 0 ; i < val; i++) { printf("This is i = %d\n", i); } } int main() { verly_long_function_xjsakdghajkshdlasjkldashjkldhasjklfdsjkhfsdjkhfsdjklhdsjkl_v1(5); verly_long_function_xjsakdghajkshdlasjkldashjkldhasjklfdsjkhfsdjkhfsdjklhdsjkl_v2(5); }
操作过程及现象
$ gcc test_long_fnames_in_elf.c -g -o test_long_fnames_in_elf.elf $ readelf -a test_long_fnames_in_elf.elf | grep long 41: 0000000000000000 0 FILE LOCAL DEFAULT ABS test_long_fnames_in_elf.c 52: 000000000040052d 61 FUNC GLOBAL DEFAULT 13 verly_long_function_xjsak # 函数符号被截断 62: 000000000040056a 61 FUNC GLOBAL DEFAULT 13 verly_long_function_xjsak # 函数符号被截断
解决方案
可以通过指定链接器参数解决该问题,具体操作如下:
使用--hash-style=gnu链接器参数
GCC 4.8.x系列默认采用SysV风格哈希表,这种格式会限制符号名称长度。通过传递--hash-style=gnu参数给链接器,切换为GNU风格哈希表,即可支持完整的长符号名。
修改后的编译命令:
gcc test_long_fnames_in_elf.c -g -Wl,--hash-style=gnu -o test_long_fnames_in_elf.elf
验证效果
重新编译后,再次用readelf查看符号:
$ readelf -a test_long_fnames_in_elf.elf | grep long # 此时会显示完整的函数名,不再被截断 52: 000000000040052d 61 FUNC GLOBAL DEFAULT 13 verly_long_function_xjsakdghajkshdlasjkldashjkldhasjklfdsjkhfsdjkhfsdjklhdsjkl_v1 62: 000000000040056a 61 FUNC GLOBAL DEFAULT 13 verly_long_function_xjsakdghajkshdlasjkldashjkldhasjklfdsjkhfsdjkhfsdjklhdsjkl_v2
补充说明
GCC 5.0及以后版本默认使用GNU风格哈希表,不会出现长符号被截断的问题,仅4.8.x这类旧版本需要手动指定该参数。
内容的提问来源于stack exchange,提问作者Alon Meirson
相关产品推荐
相关产品推荐

