作者:小仙女 | 来源:互联网 | 2024-11-14 10:07
我有一个从 C 项目编译的.o
文件,该文件引用了名为init_static_pools
的函数。我使用objdump -t
来显示其符号依赖信息:
00000000 UND 00000000 init_static_pools
根据此thread, UND 只是说“ 我需要其他人来提供该功能”。
因此,我将此.o
文件链接到一个.elf
文件,该文件包含init_static_pools
的定义。 objdump -t
显示此文件中的符号确实是 :
00004dcf g F .text 00000048 init_static_pools
根据此thread,g
和F
标志表示它是 glbal函数。我想这意味着该功能可以静态链接。
我尝试通过以下命令行将.o
文件和.elf
文件链接:
/ usr / bin / c ++ -m32 -rdynamic unittest1.o -o unittest1 target.elf
lib / libgtest.a lib / libgtest_main.a -lpthread
我遇到了以下错误:
unittest1.cc :(。text + 0x2d):对“ init_static_pools”的未定义引用
该功能仅位于.so文件中,为什么无法链接?
这可能与动态链接和静态链接之间的不同符号解析机制有关吗?因为我使用objdump -f
并看到target.elf
是动态对象。如下图所示:
target.elf:文件格式elf32-i386
体系结构:i386,标记为0x00000150:
HAS_SYMS,动态,D_PAGED
起始地址0x00001144
2019年11月6日上午1-9:17
根据 @EmployedRussian 的评论,我尝试了readelf
。
对于target.elf
,它仅包含1行:
486:00004dcf 72 FUNC GLOBAL DEFAULT 13 init_static_pools
对于unittest1.o
,它包含两行,内容为:
0000002d 0000fb04 R_386_PLT32 00000000 init_static_pools
和
251:00000000 0 notyPE全局默认UND init_static_pools
为了完成,它们的标题是:
target.elf
:
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement,little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x1144
Start of program headers: 52 (bytes into file)
Start of section headers: 246936 (bytes into file)
flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 9
Size of section headers: 40 (bytes)
Number of section headers: 43
Section header string table index: 42
unittest1.o
:
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement,little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 36988 (bytes into file)
flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)
Number of section headers: 262
Section header string table index: 261
到目前为止,我还不能说出链接失败的根本原因。幸运的是,我刚在 the series的链接器上找到了Ian Lance Taylor。希望能启发我。但是我想这需要一些时间。
ADD 2-2019/11/6上午10:33
基于@EmployedRussian的回复,我尝试了以下命令:
nm target.elf | grep init_static_pools
nm -D target.elf | grep init_static_pools
就像@EmployedRussian怀疑的那样,第二个命令行没有输出。因此,这意味着 target.elf不在其动态符号表中导出init_static_pools,这使得该符号不符合从target.elf外部进行链接的条件。
下面是一些与target.elf
的链接有关的标志:
-Wl,-T zephyr/linker.cmd (this is quite long,but it seems to be mostly layout info)
-Wl,-Map=target_prebuilt.map
-Wl,--whole-archive
-Wl,--gc-sections
-Wl,--build-id=none
-Wl,--sort-common=descending
-Wl,--sort-section=alignment
-ldl
-lm
还是我也应该检查编译标志?
我找到了--export-all-symbols,--export-dynamic,--gc-keep-exported选项,我正在尝试。
似乎--export-all-symbols
被忽略了。我想这是针对DLL的。
我将--export-dynamic
和--gc-keep-exported
放在一起,构建就可以通过。
但是nm -D
仍显示以下消息:
target.elf:没有符号
ADD 3-2019/11/6上午11:16
有关动态符号表(.dynsym)和符号表(.symtab)的文章。
https://blogs.oracle.com/solaris/inside-elf-symbol-tables-v2
一些报价:
实际上,在可共享库和动态链接出现之前,
在运行时不需要。只有一个不可分配的
符号表(合理命名为“ symtab”)。当动态链接是
添加到系统中后,原始设计师面临一个选择:
symtab可分配,或提供第二个较小的可分配副本。的
运行时所需的符号只是总数的一小部分,因此一秒钟
符号表可在运行过程中保存虚拟内存。这是一
重要的考虑。因此,发明了第二个符号表
动态链接,因此命名为“ dynsym”。
因此,我认为.dynsym
是用于运行时动态链接的。但是我想我的unittest1.o
和target.elf
在构建时会被静态链接。
所以这引出了我这个问题:我可以静态链接到.ELF
文件吗?在Windows上,我通常静态链接到.lib
文件而不是{ {1}}文件。这里的.DLL
文件看起来更像.ELF
。顺便说一句,我的构建过程还生成了一个.DLL
文件。我应该用它代替libtarget.a
吗?
不幸的是,我在target.elf
上尝试了nm -t
和readelf -s
,但它们都没有显示libtarget.a
的存在。
顺便说一句,如果您对我的问题有所了解,请放一些提示。谢谢!
对于target.elf,它仅包含1行,即:
486: 00004dcf 72 FUNC GLOBAL DEFAULT 13 init_static_pools
不幸的是,这还不足以肯定发生了什么。
要确定,请运行以下两个命令:
nm target.elf | grep init_static_pools
nm -D target.elf | grep init_static_pools
我怀疑第一个命令会产生输出,而第二个命令不会产生输出。
如果是这种情况,那么target.elf
不会 导出其动态符号表中的init_static_pools
,这使得该符号不适合从{{ 1}}。
关于您最终如何不导出该符号,我只能猜测(因为您没有提供用于链接它的链接命令)。您可能使用隐藏它的链接描述文件。