为什么 arm-poky-linux-gnueabi-gcc 链接器不使用它所说的在 C 库上找到的符号的定义?

why does the arm-poky-linux-gnueabi-gcc linker not use the definition of a symbol that it says it found on the C-library?

提问人:krammer 提问时间:11/15/2023 最后编辑:krammer 更新时间:11/15/2023 访问量:33

问:

#include<stdio.h>
//#include<sys/io.h>
extern        int ioperm(unsigned long from, unsigned long num, int turn_on);
int main()

{
 unsigned long from, num;
  int turn_on;
 ioperm( from,num,  turn_on);
 return 0;
}

当我使用链接此程序时

arm-poky-linux-gnueabi-gcc -Wl,--trace-symbol=ioperm -v -march=armv7-a -marm -mfpu=neon -mfloat-abi=hard -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=<$PWD>sdk/sysroots/armv7ahf-neon-poky-linux-gnueabi hello.o -o hello_out

输出如下所示

<$PWD>/sdk/sysroots/armv7ahf-neon-poky-linux-gnueabi/lib/libc.so.6: definition of ioperm

hello.o:hello.c:function main: error: undefined reference to 'ioperm'

那么,链接器也找到了这个符号,但无法使用它?为什么?

如果我在这个库上看到 dyn-syms,它如下所示:

arm-poky-linux-gnueabi-readelf --dyn-syms <$PWD>/sdk/sysroots/armv7ahf-neon-poky-linux-gnueabi/lib/libc-2.31.so | grep ioperm 437: 000d4cf0 32 FUNC GLOBAL DEFAULT 13 ioperm@GLIBC_2.4

使用的 gcc 版本是 *gcc 版本 9.3.0 (GCC) *

我有另一个开放的嵌入式 arm 工具链,其中 gcc 编译器是 arm-oe-linux-gnueabi-gcc。它的版本是 6.4.0,其中 glibc libc-2.26.so,符号定义为 在这个开放嵌入的工具链中,符号被正确链接。如何从链接器中获取有关其未在 yocto 工具链中使用符号定义的原因的更多信息? 此外,在 yocto 工具链中,此符号不会在任何地方声明,因为头文件 <sys/io.h> 也丢失了。我想知道为什么 glibc 说即使标题甚至不存在也找到了定义?418: 000dfcd8 396 FUNC WEAK DEFAULT 11 ioperm@@GLIBC_2.4

此外,在 yocto 工具链上,只有此符号会导致问题。其他 C 语言 sumbol 对链接器没有任何问题。

GCC yocto ld glibc openembedded

评论


答:

0赞 Ross Burton 11/15/2023 #1

从 ioperm 手册页:

“这个电话主要是针对 i386 架构的。在许多其他架构上,它不存在或总是返回错误。

glibc 在 2.30 之前的实现,用代码的话来说,是“虚构的”,之后它们就不存在了。

基本上,除非您使用的是 32 位 x86,否则不要使用 ioperm() 和 friends。

评论

0赞 krammer 11/16/2023
非常有趣,非常感谢您对手册页的引用,并适当注意以避免它。现在,我使用的 glibc libc-2.31.so。但是,如果我如上所述使用 readelf dyn-syms 查看 glibc,该符号仍然存在。有没有办法从链接器获得一些额外的详细输出,说明为什么它没有使用该符号,即使它找到了该符号(我使用 -Wl,--trace-symbol=ioperm 验证了它)。思潮?