如何强制GCC在ELF可执行文件/共享库中包含.symtab节?
如何强制GCC在ELF可执行文件/共享库中保留.symtab节
嘿,先给你提个小细节:你用readelf -l看的是ELF的**段(Segment)**映射,但.symtab是个非加载的节——它不会被加载到进程内存里,所以在段列表里根本找不到它。要检查.symtab有没有被保留,得用readelf -S <你的文件路径>这个命令,看输出里有没有.symtab的条目。
接下来聊聊为什么你试的-static和-ggdb没生效:
-static只是让程序静态链接,但如果链接器默认会丢弃非必要的节(比如有些环境下链接器会自动strip掉冗余符号表),.symtab还是会被删掉;-ggdb是生成更详细的调试符号,但如果链接阶段链接器直接把.symtab扔了,那调试信息再全也留不住这个节。
要搞定这个问题,核心是告诉链接器别丢.symtab,分两种场景给你具体命令:
1. 生成可执行文件(动态/静态链接都适用)
编译时加上链接器选项-Wl,--keep-section=.symtab,同时别加-s(这个选项会强制strip所有符号表)。比如:
gcc -ggdb your_source.c -o your_exec -Wl,--keep-section=.symtab
如果要静态链接,再加-static就行:
gcc -static -ggdb your_source.c -o your_exec -Wl,--keep-section=.symtab
2. 生成共享库(.so文件)
共享库默认链接时只会保留用于动态链接的.dynsym,.symtab会被主动丢弃。所以同样要加--keep-section=.symtab,配合-g生成完整符号表:
gcc -fPIC -shared -ggdb your_lib_source.c -o your_lib.so -Wl,--keep-section=.symtab
几个额外提醒
- 如果你编译时不小心加了
-s,一定要删掉,这个选项会直接把.symtab抹掉; - 别对生成的文件执行
strip命令,它也会删掉.symtab; - 快速检查的小技巧:用
readelf -S your_file | grep symtab,如果能看到.symtab的条目,就说明成功保留了。
内容的提问来源于stack exchange,提问作者Trey
相关产品推荐
相关产品推荐

