我知道有很多关于共享和静态库的用例的问题,这个问题与此无关.我问的是存储在磁盘上的文件格式的差异.
为什么问题是,两者之间有什么区别?或者它们是否完全相同,仅在使用方面有所不同?
我认为它们不一样,因为在共享库上运行'nm'需要-D标志.显然,它需要做一些不同的事情.为什么?
它们都是ELF文件吗?
共享库可以包含某些依赖路径的唯一区别是什么?
静态库,例如libfoo.a
,不是任何类型的可执行文件.它只是
其他文件的unix ar
格式的索引存档,恰好是ELF
目标文件.
像任何存档一样创建静态库:
ar crs libfoo.a objfile0.o objfile1.0...objfileN.o
输出新的archive(c
)libfoo.a,其中包含那些对象文件inserted(r
)和index(s
).
你会听到程序中的链接 libfoo.a
.这并不意味着它
libfoo.a
本身与程序相关联或与程序相关联.这意味着它libfoo.a
作为一个存档传递给链接器,它可以从中提取程序所需的存档中的目标文件并将其链接到程序中.因此,静态库(ar
格式)的格式只是链接器输入的对象文件绑定格式:它同样可能是其他一些捆绑格式,对链接器的任务没有任何影响,即消化一组目标文件和共享库并从中生成程序或共享库.ar
格式是历史的选择.
另一方面,共享库,例如libfoo.so
,是 ELF文件而不是任何类型的存档.
不要被诱惑怀疑静态库是一个事实,即所有的知名ELF-解析器一种ELF文件- ,,objdump
-将解析静态libary.这些工具都知道,一个静态库是一个归档的 ELF目标文件,所以他们只是解析库中的所有目标文件,如果你已经列出他们在命令行上.readelf
nm
使用该-D
选项nm
只是指示工具只选择它解析的ELF文件的动态符号表中的符号(如果有的话) - 运行时链接程序可见的符号 - 无论是什么是否从存档中解析它们.它objdump -T
和readelf --dyn-syms
.一样.这是不是
必要使用这些选项从一个共享库中解析符号.如果您不这样做,那么默认情况下您只会看到完整的符号表.如果您nm -D
在静态库上运行,您将被告知no symbols
,对于归档中的每个目标文件 - 同样如果您nm -D
单独运行每个目标文件.原因是目标文件没有动态符号表:只有共享库或程序有一个.
目标文件,共享库和程序都是ELF格式的变体.如果您对ELF变体感兴趣,那些是感兴趣的变体.
ELF格式本身是一个冗长而棘手的技术阅读,是精确区分变体的必要背景.简介:ELF文件包含ELF头结构,其中一个字段包含文件的类型标识符作为目标文件,共享库或程序.当文件是程序或共享库时,它还包含一个可选的程序头表结构,其字段为运行时链接程序/加载程序提供在进程中加载文件所需的参数.就ELF结构而言,程序和共享库之间的差异很小:它是详细的内容,它们对从加载器中引出的行为产生影响.
对于漫长而棘手的技术阅读,请尝试Excutable和Linkable Format(ELF)