如何查看.so文件的目标文件内容

4
如何查看哪些 .o 文件构成了 .so 文件?
意味着如何从 .so 文件中注意到用于构建 .so 文件的目标文件是什么(如果我只有 .so 文件).
1个回答

7

仅从一个共享库中无法确定编译成它的目标文件。如果幸运的话,您可能能够做出合理的猜测。

共享库是由链接器从目标文件和其他共享库制作而成的,但它并不包含用于构建它的目标文件或共享库。相反,静态库由存档程序ar制作,它包含目标文件:它只是目标文件的ar归档。

如果共享库未被剥离调试信息,则为了调试目的,其符号表将包含链接到共享库中的那些目标文件所编译的文件的名称——至少是那些使用调试信息编译的源文件。通过那些源文件的名称,您可以推断出目标文件的名称,但不能确定。

例如,在这里我们从源文件foo.cbar.c制作一个共享库。

将源文件编译为目标文件:

$ gcc -Wall -fPIC -c -o foo.o foo.c
$ gcc -Wall -fPIC -c -o bar.o bar.c

将目标文件链接起来以创建共享库:

$ gcc -shared -o libfoobar.so foo.o bar.o

然后:

$ readelf -s libfoobar.so | grep FILE
26: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
35: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS foo.c
37: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS bar.c
39: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
42: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS 

这句话的意思是三个源文件都为该库提供了调试信息,因此我们可以推断它们编译的目标文件可能是:

crtstuff.o
foo.o
bar.o

请注意,crtstuff.c 不是我们编译的源文件之一。它实际上包含了 C 运行库的初始化和结束代码,并且这些代码是从默认链接的 C 运行对象文件中被添加到我们的库中的。
由于以下原因,这个推断可能对任何一个文件都是错误的:
$ gcc -Wall -fPIC -c -o abc.o foo.c
$ gcc -Wall -fPIC -c -o xyz.o bar.c
$ gcc -shared -o libfoobar.so abc.o xyz.o

这也是一种完全可行的编译和链接库的方式。

如果库中已经去除了调试信息:

$ strip -g libfoobar.so

那么我们就没有希望了:
$ readelf -s libfoobar.so | grep FILE
$

不再使用FILE符号。


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