我的问题源于我给出的共享库,没有重新编译库的选项。错误说明undefined reference to memcpy@GLIBC_2.14
。
我机器上的GLIBC版本是2.12。我见过人们使用该线路在线完成的修复工作
__asm__(".symver memcpy,memcpy@GLIBC_2.2.5");
我做的修复是使用十六进制编辑器将2.14的引用更改为GLIBC_2.2.5。执行命令readelf -V lib_name.so
时,输出更改为:
0x0060 Name: GLIBC_2.14 Flags: none Version 6
......
0x0080 Name: GLIBC_2.2.5 Flags: none Version 4
至:
0x0060 Name: GLIBC_2.2.5 Flags: none Version 6
......
0x0080 Name: GLIBC_2.2.5 Flags: none Version 4
这解决了我的错误。我想知道的是它会产生什么样的影响。我试图研究memcpy与memmove以及从GLIBC_2.14开始对memcpy的更改,但我不太明白发生了什么以及memcpy的原始问题是什么。我担心这个“修复”,虽然它允许我的程序运行,以防memcpy正在做的事情表现不正常。为什么我在网上看到的所有修复程序都专门链接到2.2.5版本?
如果有人能给我一些关于这个主题的见解或提供一些相关信息的链接,我将不胜感激。
我想知道的是它会产生什么样的影响。
最可能的影响是,当您的第三方库第一次调用memcpy
时,它会崩溃。
有一个原因引入了新版本的memcpy@GLIBC_2.14
:它与旧的memcpy
不是ABI兼容的(这里发生的是GLIBC-2.14,memcpy
是GNU_IFUNC
,这意味着它返回实际memcpy
的地址;代码然后在第三方库中调用返回的例程。但memcpy@GLIBC_2.2.5
的返回值是目标参数而不是函数地址,所以你应该立即崩溃)。
如果有人能给我一些见解
您获得的图书馆需要GLIBC-2.14。通过在GLIBC-2.12机器上运行它,您已经取消了所有保修。你最好的选择是:
更新:
我没有使用memcpy返回的值
你不明白GNU_IFUNC
s是如何工作的。这是一个description。问题是,当您没有使用返回值时,动态链接器会这样做。
动态链接器中的代码执行如下操作:
if (symbol type == STT_GNU_IFUNC) {
// call the IFUNC to get an address of the actual implementation
void (*pfun)() = memcpy();
// call the actual (non-IFUNC) implementation of memcpy.
return (*pfun)(to, from, size); // You will crash here!
}
通过asm hack替换非ifunc
版本为infunc
版本,你保证pfun == to
,所以你的to
被调用就好像它是一个函数。那通常应该立即SIGSEGV
。