如何使共享库成为可执行文件

时间:2016-01-13 12:42:18

标签: c operating-system shared-libraries executable x86-64

我正在寻找被问到的问题。我看到这个链接https://hev.cc/2512.html正在做我想要的完全相同的事情。但是没有解释最新情况。我也很困惑,如果是的话,是否可以将带有main()的共享库变为可执行文件?我猜我必须给全局main()但不知道细节。非常感谢任何进一步简单的参考和指导

我正在使用内核3.13的x86-64 64位Ubuntu

3 个答案:

答案 0 :(得分:3)

这从根本上说是不明智的。

共享库通常没有执行的任务,因为它等同于main()函数。主要目标是允许单独管理和实现公共代码操作,以及以这种方式运行以允许加载和共享单个代码文件的系统,从而减少使用它的应用程序代码的内存开销。

可执行文件设计为具有单个入口点,从该入口点执行与完成定义良好的任务相关的所有操作。不同的操作系统对该入口点有不同的要求。共享库通常没有类似的底层函数。

因此,为了(有用地)将共享库转换为可执行文件,您还必须定义(并生成代码)可以从单个入口点启动的任务。

您链接的代码从库的源代码开始,并通过入口点函数显式编码它调用的main()。如果您没有库的源代码,理论上可以从共享库中破解新文件(在没有安全功能的情况下,在任何给定的操作系统中都可以防止这种情况),但这样做会很奇怪

但实际上你不会以这种方式部署代码。相反,您可以将共享库编码为共享库。如果您想执行某项任务,您可以编写链接到该库和代码的单独可执行文件。试图将两者结合在一起会破坏编写库的目的,并扭曲该库和应用程序的结构,实现和维护。保持应用程序和库分开。

答案 1 :(得分:1)

我不知道这对任何事情都有用。您可以始终在单独的二进制文件中使用main来实现相同的功能,该二进制文件链接到该库。制作一个既可以作为两者的单个文件,也可以在愚蠢的计算机技巧和#34;中实现。我可以看到在库中嵌入main没有任何好处,即使它是测试工具或其他东西。

可能有一些性能原因,比如没有函数调用通过PLT的间接。

在该示例中,共享库也是一个有效的ELF可执行文件,因为它有一个快速而肮脏的入口点,可以从the ABI所说的main抓取init_args的args(即将它们从堆栈复制到寄存器中)。它还安排正确设置ELF解释器。它只适用于x86-64,因为没有为其他平台提供extern char **environ;的定义。

我很惊讶它确实有效;我认为通常的CRT(启动)代码所做的所有废话实际上都需要stdio才能正常工作。看起来它没有初始化argc,因为它只从堆栈中获取argvenvp,而不是main

无论如何,当作为可执行文件运行时,它拥有一切有效的动态链接可执行文件:一个运行一些代码和退出的入口点,一个解释器,以及对libc的依赖。 (ELF共享库可以依赖(即链接)其他ELF共享库,与可执行文件的方式相同)。

当用作库时,它只是作为包含一些函数定义的普通库。甚至没有看到让它作为可执行文件(入口点和解释器)工作的东西。

我不确定为什么你不会因main()的多个定义而出错,因为它没有被声明为"weak" symbol。我想只有在引用未定义的符号时才会查找shared-lib定义。因此,来自call.c的{​​{1}}代替来自main()的{​​{1}},因为libtest.so在链接器查看main之前已经有了定义。

答案 2 :(得分:0)

  • 使用Example创建共享动态库。

  

假设有三个文件:sum.o mul.o和print.o

     

共享库名称" libmno.so"

cc -shared -o libmno.so sum.o mul.o print.o
  

并使用

进行编译
cc main.c ./libmno.so