2016-01-13 76 views
2

我正在寻找问题。我看到这个链接https://hev.cc/2512.html这是做我完全一样的东西,我想要的。但没有解释发生了什么事情。我也困惑是否可以使用带main()的共享库来执行,如果是的话,怎么办?我可以猜想我必须给全球主要(),但不知道细节。任何进一步的参考和指导是非常赞赏如何使共享库可执行

我的工作X86-64 64位的Ubuntu内核3.13

+0

什么平台你想做到这一点呢? – fuz

+0

添加了平台和内核版本 – shami

回答

1

我不明白这对任何事物都有用。您可以始终使用与该库链接的单独二进制文件中的main获得相同的功能。制作一个可以同时工作的单一文件,在“愚蠢的电脑技巧”领域是稳固的。即使它是一个测试工具或其他东西,我也可以看到嵌入库中的main没有任何好处。

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


在该示例中,共享库也是一个有效的ELF可执行文件,因为它有一个快速和肮脏的入口点从哪里the ABI说,他们去抓住args作为main(即从它们拷贝该堆栈进入寄存器)。它还安排正确设置ELF解释器。它只能在x86-64上工作,因为没有为其他平台的init_args提供定义。

我很惊讶它的实际工作;我认为通常的CRT(启动)代码确实需要stdio才能正常工作。它看起来像它不初始化extern char **environ;,因为它只是变得argcargv从堆栈,不envp

无论如何,当作为一个可执行文件运行,它必须是一个有效的动态链接可执行文件所需要的一切:它运行一些代码和退出,一个解释,并依赖于libc的入口点。 (ELF共享库可以依赖于(即链接)其他ELF共享库,就像可执行文件可以)。


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

我不确定为什么您因为main的多个定义没有出错,因为它没有被声明为"weak" symbol。我想只有在有一个未定义符号的引用时才会查找共享库定义。所以main()call.c用来代替main()libtest.so因为main已经有一个定义链接看libtest之前。

3

这根本不是什么明智的。

共享库通常没有它可以使用的任务,因为它相当于main()函数。主要目标是允许对通用代码操作进行单独管理和实施,并且允许在运行该方式的系统上允许加载和共享单个代码文件,从而减少使用它的应用程序代码的内存开销。

可执行文件被设计为具有单一入口点,从该入口点执行与完成明确定义的任务有关的所有操作。不同的操作系统对该入口点有不同的要求。共享库通常没有类似的基础功能。

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

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

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

+0

我正在尝试编写以特殊方式加载二进制文件的引用监视器。共享库在这种情况下是一个明智的解决方案。我对吗?是的,你是正确的共享库会生成守护进程来进一步限制加载进程的执行。 – shami

0
  • 使用示例创建共享动态库。

假设用有三个文件分别是:sum.o mul.o和print.o

共享库名称 “libmno.so”

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

并与

cc main.c ./libmno.so