You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

针对已知依赖可执行集的共享库剥离未使用符号的工具问询

针对共享对象未使用符号的剥离方案

可用工具与核心思路

你可以借助GNU binutils工具链(objcopy、ld、nm)或LLVM对应工具,结合你已提取的被引用符号集,精准剥离共享对象(.so)中的未使用符号。核心是只保留被依赖ELF直接/间接引用的符号与代码,避免误删依赖链上的内容。

具体操作步骤

前提准备

如果你的共享对象编译时未添加-ffunction-sections -fdata-sections参数,建议重新编译时加上。这两个参数会把每个函数、数据项放到独立的section中,能实现更细粒度的代码剥离;如果无法重新编译,只能基于符号级剥离(粒度较粗)。


方法一:手动符号过滤(适合无法重编译SO的场景)

  1. 提取SO的所有全局定义符号
    nm -D --defined-only libtarget.so | awk '{print $3}' > all_so_symbols.txt
    
  2. 生成需保留的符号列表
    将你已提取的被依赖ELF引用的符号集,与all_so_symbols.txt取交集,得到keep_symbols.txt(每行一个符号)。注意C++符号要保留名字修饰后的完整名称。
  3. 执行符号剥离
    objcopy --keep-symbols=keep_symbols.txt libtarget.so libtarget_stripped.so
    

    注意:这种方式只会保留你指定的符号,但如果某个保留符号依赖了未被直接引用的其他符号,这些依赖符号会被误删。因此需要提前分析符号依赖链,把间接依赖的符号也加入keep_symbols.txt。


方法二:链接器智能GC(适合可重编译SO的场景)

利用链接器的--gc-sections参数自动清理未被引用的section,同时强制保留被依赖ELF需要的符号:

  1. 收集需强制保留的符号
    将你提取的被引用符号集保存到required_symbols.txt,每行一个符号。
  2. 重新链接SO并清理未使用代码
    ld -shared --gc-sections -o libtarget_stripped.so libtarget.o --undefined=@required_symbols.txt
    
    (部分版本的ld可能不支持@file语法,可改为逐个添加-u symbol参数)
    链接器会自动保留所有被强制保留的符号,以及这些符号依赖的所有子符号与section,彻底删除未被引用的代码。

方法三:LLVM工具链替代方案

如果你的嵌入式平台使用LLVM工具链,可替换为llvm-objcopy、llvm-link执行上述操作,语法与GNU工具基本一致,适配LLVM生态的编译环境。

关键验证步骤

剥离完成后必须做验证,避免线上崩溃:

  • 用nm -D libtarget_stripped.so确认关键符号已保留
  • 用readelf -S libtarget_stripped.so检查section数量是否减少
  • 在目标平台运行所有依赖该SO的可执行文件/库,确保无undefined symbol或运行时异常

内容的提问来源于stack exchange,提问作者SWE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 21:52:31