当将静态库和.o文件链接到共享库时,我遇到了丢失符号的问题。我已经检查了静态库的符号表,我需要在表中列出的函数,如下所示:
...
00000000 g F .text 000000b0 av_int2dbl
...
000000b0 g F .text 00000060 av_int2flt
但是当我生成共享库时,av_int2dbl
和av_int2flt
以及其他一些函数
错过了(他们都通常在静态symtable中列出),我使用了一个愚蠢的方法来解决这个问题,通过在.o文件中创建一个虚函数,并引用从虚函数中错过的函数,共享库的DYNAMIC SYMBOL TABLE添加以前错过的一些功能,但奇怪的是av_int2dbl
和av_int2flt
错过了。
有人能告诉我,生成共享库时删除符号的原理是什么?
如果ld
将删除所有未经过修改的符号,为什么在.o文件中定义的函数(这些函数不会从其他位置引用)仍然存在于共享库中?为什么在虚拟函数中显式调用av_int2dbl
和av_int2flt
,而反汇编会丢失这两个函数?
下面是.o文件中定义的虚函数:
int my_dummy_funcs(void)
{
av_rdft_init(0x01,0x1);
av_rdft_calc(NULL, NULL);
av_rdft_end(NULL);
av_int2dbl(1);
av_int2flt(1);
av_resample(NULL,NULL,NULL,NULL,0,0,0);
av_resample_close(NULL);
av_resample_init(0,0,0,0,0,1.0);
return 0;
}
按如下方式反汇编虚拟函数:
0008951c <my_dummy_funcs>:
8951c: e3a00001 mov r0, #1
89520: e92d40d0 push {r4, r6, r7, lr}
89524: e1a01000 mov r1, r0
89528: e3a04000 mov r4, #0
8952c: e24dd010 sub sp, sp, #16
89530: eb03a21e bl 171db0 <av_rdft_init>
89534: e1a01004 mov r1, r4
89538: e1a00004 mov r0, r4
8953c: e3a06000 mov r6, #0
89540: eb03a22f bl 171e04 <av_rdft_calc>
89544: e1a00004 mov r0, r4
89548: eb03a231 bl 171e14 <av_rdft_end>
8954c: e1a01004 mov r1, r4
89550: e1a02004 mov r2, r4
89554: e1a03004 mov r3, r4
89558: e1a00004 mov r0, r4
8955c: e58d4000 str r4, [sp]
89560: e58d4004 str r4, [sp, #4]
89564: e3a07000 mov r7, #0
89568: e58d4008 str r4, [sp, #8]
8956c: eb0e4a62 bl 41befc <av_resample>
89570: e1a00004 mov r0, r4
89574: e3437ff0 movt r7, #16368 ; 0x3ff0
89578: eb0e4a4a bl 41bea8 <av_resample_close>
8957c: e1a00004 mov r0, r4
89580: e1a01004 mov r1, r4
89584: e1a02004 mov r2, r4
89588: e1a03004 mov r3, r4
8958c: e58d4000 str r4, [sp]
89590: e1cd60f8 strd r6, [sp, #8]
89594: eb0e495f bl 41bb18 <av_resample_init>
89598: e1a00004 mov r0, r4
8959c: e28dd010 add sp, sp, #16
895a0: e8bd80d0 pop {r4, r6, r7, pc}
答案 0 :(得分:0)
但是当我生成共享库时,av_int2dbl和av_int2flt以及其他一些函数错过了
最可能的原因是:它们在常规符号表中标记为HIDDEN
, 告诉链接器不将它们导出到动态符号表中。
您可以通过运行
来验证此假设readelf -s libfoo.a | grep av_int2dbl
(并学会在ELF平台上使用readelf
代替objdump
。