移除、混淆静态库中多余的符号(待续)

生成库的时候,只想暴露接口符号给调用者,其他的符号需要删除,怎么办?

方法1

#hidden符号增加local flag
objcopy --strip-uneeded --localize-hidden libxxx.a

#设置所有符号为local(可能有副作用)
objcopy -G not_exist_sym libxxx.a

#根据need_globals_symbols_list.txt,将其中所有符号设置为global
objcopy --globalize-symbols=need_globals_symbols_list.txt libxxx.a

#移除local符号
strip -x libxxx.a

#移除其他非local符号
strip -N sym_name libxxx.a

#只保留某些符号
strip -s -K sym_name libxxx.a

#轻度混淆,重命名section和无法strip的symbol
objcopy --redefine-sym old_sym=new_sym libxxx.a
objcopy --rename-section old_sect=new_sect libxxx.a

这个方法适合没有源码的情况,缺点有:

     1.原始库需要被删除的符号必须是hidden (即编译时参数 -fvisibility=hidden 或手动指定 __attribute((visibility("hidden")))   ),否则objcopy无法将其设置为local,也就无法被strip -x移除,当然用strip -N也可以,就是麻烦。objcopy -G not_exist_sym libxxx.a会将除not_exist_sym之外所有符号设置为local,如果没有副作用,那就可以解决这个缺点。

     2.当原始库需要被删除的符号是内部调用的符号(例如source1.c 中调用了source2.c的函数),不管是不是hidden,此符号都处于relocation,无法被strip移除,只能--redefine-sym --rename-section一个个修改混淆。即便如此,该符号的地址依然存在。

    3.未被strip的local状态的符号可以被objdump nm看到,但不可被链接,实际上只要用objcopy --globalize-symbol=sym_name libxxx.a即可让其重新可链接。

    4.库使用-ffunction-sections -fdata-sections编译时,即便strip了符号,section name依然存在。

方法2

#源码里,需要暴露的符号用__attribute((visibility("default"))),编译时增加参数
gcc -c *.c -o output.o -fvisibility=hidden

#链接,只保留default或protected的global符号
ld -r output.o --gc-sections --gc-keep-exported -o libxxx.o
gcc-ar rcs -o libxxx.o libxxx.a

缺点:

    1.需要有源码

    2.依然不会删除内部调用的符号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值