将已编译的库链接到更新版本的glibc

9

我正在处理一个项目,使用ftdi D2XX驱动器与ENTTEC DMX usb pro设备进行接口交互。 ftdi驱动程序(存储在/ usr / local / lib /中的libftdi2xx.so.1.1.12)针对glibc v2.14或更高版本进行编译。

我正在debian 7上开发,该系统仅支持glibc v2.13及以下版本。当执行我编写的C代码(调用ftdi驱动程序)时,会出现错误:

./a.out: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by /usr/local/lib/libftd2xx.so)

考虑到glibc版本不兼容,这是有道理的。我已经将最新版的glibc(v2.17)下载并安装到我的计算机的临时目录(“~/glibc-testing/install/lib/”)中,并使用以下命令:

~/glibc-testing/install/lib/ld-linux-x86-64.so.2 --library-path ~/glibc-testing/install/lib/ ./a.out 

通过这个调用,我能够成功运行C代码。
我想将这个C代码编译成共享库。它将用于与DMX设备进行接口交互,并由使用C#开发的主应用程序调用。
我不确定如何继续前进。看起来我需要告诉fdti驱动程序始终使用较新的glibc,同时让其余应用程序使用普通库。ftdi 2DXX驱动程序仅可预编译(无源代码可用)。是否有一种方法将这个预编译程序链接到新库?
我已经研究了导出LD_LIBRARY_PATH=/home/.../glibc/install/lib/的选项,但效果甚微。
谢谢!

5
唯一明智的行动是尝试与制造驱动程序的人进行沟通,并请求链接到旧版本glibc的版本。 - Nikos C.
你尝试过使用LD_PRELOAD吗? - maha
我认为设置rpath应该可以解决问题,请参见这里。甚至可以在编译后的应用程序中重置rpath,详情请参见此处 - Bort
1
为什么应用程序的其余部分使用旧版glibc很重要?这太疯狂了。如果您无法获得针对旧版glibc链接的驱动程序,则应使用新版构建整个应用程序。无论如何,您在运行时都需要新版本。 - John Bollinger
1
为了超越尼科斯的评论,我会特别要求一个符合 Linux 标准基础规范 (LSB) 某个版本的驱动程序。实际上,供应商分发一个不符合 LSB 规范的用户模式驱动程序没有任何好处。 - cha5on
3个回答

1
你可以在你自己的代码中提供缺失的函数,但请注意这些函数是有版本号的,你可以提供一个映射文件或者与代码一起完成。例如:
#define SYMVER(ver, sym) __asm__(".symver " #sym "," #sym "@" #ver "\n")

SYMVER(GLIBC_2.14, foo);
int foo(int a, char *b)
{
    return 4;
}

为了确定需要实现什么,你可以使用readelf命令:
readelf -s /usr/local/lib/libftd2xx.so | grep '@GLIBC_2\.14'

这就是函数的全部内容。
现在,让加载器相信它得到了正确的库(除非您想要实现自己的加载器),这就是棘手的部分,为此,您需要修补库以删除对GLIBC_2.14的引用,因为它将专门查找libc。
有几种方法可以进行; 迄今为止最简单的方法是将GLIBC_2.14替换为GLIBC_2.13,只需记住您需要使用替换版本(即GLIBC_2.13)定义您的符号,因为版本是按引用存储的。
有了这个,您的程序应该可以运行。
现在,理论上您可以:
  • 解析 ELF 文件,在程序头中找到 DYNAMIC 类型条目,然后查找 VERNEED 条目,在那里您应该找到需求表,可以修剪引用(如果可用,还可以使用 .gnu.version_r 部分标题到达那里)。

  • 或者,您可以编写一个加载器,链式连接标准加载器,但使用 ptrace 覆盖查找。


1

您可以使用PatchELF来修改提供的共享库的rpath:

$ patchelf --set-rpath /home/user/glibc-testing/install/lib/ libftdi2xx.so.1.1.12

然后使用以下命令编译你的共享库:

$ gcc -Wl,-rpath=/home/user/glibc-testing/install/lib/ <rest of flags>

您编译的任何可执行文件都必须使用以下方法进行编译:

$ gcc -Wl,-rpath=/home/user/glibc-testing/install/lib/  -Wl,--dynamic-linker=/home/user/glibc-testing/install/lib/ld-linux-x86-64.so.2 <rest of flags>

0

其中一种变体是将Debian更新到sid版本。

另一个选项是更改文件/etc/ld.so.conf.d/libc.conf/etc/ld.so.conf.d/x86_64-linux-gnu.conf

这些文件包含系统中搜索库的路径。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接