静态库,例如libfoo.a
不是任何类型的可执行文件。
它只是一个索引存档unix ar format https://en.wikipedia.org/wiki/Ar_(Unix)其他文件恰好是ELF https://en.wikipedia.org/wiki/Executable_and_Linkable_Format对象文件。
静态库的创建方式与任何存档一样:
ar crs libfoo.a objfile0.o objfile1.0...objfileN.o
输出新的存档(c
) libfoo.a,插入这些目标文件(r
)
并添加索引(s
).
你会听说linking libfoo.a
在一个程序中。这并不意味着libfoo.a
itself链接到程序或与程序链接。代表着libfoo.a
作为存档传递给链接器,链接器可以从中提取并链接到
程序只是程序需要的存档中的那些目标文件。
所以静态库的格式(ar
格式)只是一个目标文件
链接器输入的捆绑格式:它同样可以是其他捆绑
格式对链接器的任务没有任何影响,即消化一组
目标文件和共享库并生成程序或共享库,
从他们。ar
格式是历史的选择。
另一方面,共享库,例如libfoo.so
, isELF 文件
而不是任何类型的档案。
不要怀疑静态库是一种 ELF 文件
事实上,所有著名的 ELF 解析器 -objdump
, readelf
, nm
-
将解析静态库。这些工具都知道静态库是
档案ofELF目标文件,因此它们只是解析所有目标文件
在库中,就像您在命令行上列出它们一样。
使用-D
选项与nm
只是指示工具选择
仅动态符号表中的符号(如果有),
它解析的 ELF 文件的数量 - 运行时链接器可见的符号
- 无论它们是否是从存档中解析的。它是
与objdump -T
and readelf --dyn-syms
. It is not有必要使用这些选项来解析共享库中的符号。如果
如果你不这样做,那么默认情况下你只会看到full符号表。
如果你跑nm -D
在静态库上你会被告知no symbols
, 为了
存档中的每个目标文件 - 同样,如果您运行nm -D
对于每个
这些目标文件单独。原因是目标文件
没有动态符号表:只有共享库或程序有一个。
目标文件, 共享库 and program都是 ELF 格式的变体。
如果您对 ELF 变体感兴趣,那么这些就是您感兴趣的变体。
ELF格式本身就是一个漫长而棘手的技术阅读,并且是必需的
精确区分变体的背景。简介:ELF 文件
包含一个ELF 头其字段之一包含类型标识符的结构
将文件视为目标文件、共享库或程序。当文件是
程序或共享库,它还包含一个可选的程序头表
结构其字段为运行时链接器/加载器提供参数
它需要在进程中加载文件。从ELF结构来看,
程序和共享库之间的差异很小:
使他们的行为产生差异的详细内容
从装载机引出。
对于冗长而棘手的技术阅读,请尝试可执行和可链接格式 (ELF) https://refspecs.linuxfoundation.org/elf/TIS1.1.pdf