繁体   English   中英

gcc `-shared` 选项如何影响输出?

[英]How does gcc `-shared` option affect the output?

从技术上讲,就文件内容而言, gcc -fPIC -shared src.cgcc -fPIC src.c的输出有什么区别?

假设在src.c定义了int main(int, char**)以便两个编译都成功。 但是按预期执行由gcc -shared src.c生成的a.out会出现以下错误:

-bash: ./a_shared.out: cannot execute binary file

就算有一个main函数吧。

另外,如何使用otoolobjdump等工具检查输出文件中的差异?

非常感谢。

共享库和可执行文件使用相同的格式:它们都是可加载的图像。 然而,

  1. 共享库通常与位置无关,可执行文件通常不是。 这会影响代码生成:对于位置无关,您必须使用相对地址加载全局变量或跳转到函数。

  2. 可执行文件有一个“入口点”,它是执行开始的地方。 这通常不是main() ,因为main()是一个函数,函数返回,但执行永远不应该从入口点返回。

现在,这并没有回答关于-shared做什么的问题。 您可以使用-v标志询问 GCC。 以下是我的系统上不带和带-shared的调用之间的差异。

参数collect2-shared

-dynamic-linker
/lib64/ld-linux-x86-64.so.2
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o
/usr/lib/gcc/x86_64-linux-gnu/4.7/crtbegin.o
/usr/lib/gcc/x86_64-linux-gnu/4.7/crtend.o

对于参数collect2-shared

-shared
/usr/lib/gcc/x86_64-linux-gnu/4.7/crtbeginS.o
/usr/lib/gcc/x86_64-linux-gnu/4.7/crtendS.o

观察

看起来代码生成不受影响:您仍然必须使用-fpic-fPIC

您可以看到crt1.o (“C 运行时”)仅在链接可执行文件时包含在内。 使用nm ,我们可以找出它包含的内容:

$ nm /usr/lib/x86_64-linux-gnu/crt1.o
0000000000000000 R _IO_stdin_used
0000000000000000 D __data_start
                 U __libc_csu_fini
                 U __libc_csu_init
                 U __libc_start_main
0000000000000000 T _start
0000000000000000 W data_start
                 U main

所以你可以看到它似乎定义了一些与stdin以及_start (它是入口点)有关的东西,并且它有一个对main的未定义引用。

我不确定其余的文件是什么,但至少您知道如何找到它们,并且可以随意浏览,或者如果您愿意,可以查看源代码。

根据https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options -shared选项执行以下操作

  • 生成一个共享对象,然后可以将其与其他对象链接以形成可执行文件。

  • 并非所有系统都支持此选项。

  • 对于可预测的结果,您还必须在指定此链接器选项时指定用于编译的相同选项集(-fpic、-fPIC 或模型子选项)。

按照-shared和轮候册的区别,-shared的GCC选项传递到-shared GCC可以启用或链接时禁止其他标志。

根据我的理解,如果可执行文件具有共享库,则可执行文件的大小非常小 在共享库存在并正确链接之前,可执行文件不会运行。 使用共享库的好处是如果我们有一个非常大的代码库,我们不需要每次都构建整个代码 我们只需要重建 .so 文件并将其链接到可执行文件。 节省了大量时间

对于没有共享库的可执行文件,可执行文件的大小将非常大 对于每次代码更改,都需要构建完整的代码,这可能非常耗时

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM