一尘不染

如何从共享库中导出符号

linux

我使用Windows Host上的RVDS编译器*.so使用*.o目标代码文件(C源代码)创建了一个共享库()。

我将此共享库与一个应用程序链接(gcc用于Linux主机上的ARM目标)并获得一个可执行文件,该可执行文件在运行时会产生分段错误。(我知道我必须调试它!)

如果不创建共享库,而是创建具有相同源文件的静态库,然后与该应用程序链接,然后执行该应用程序,则可以正常运行。

所以我的问题是:

  1. 我是否需要使用某些结构在源文件中显式导出符号(导出到应用程序的功能)或任何其他符号,以便在与应用程序链接时可以正常工作?需要什么,我该怎么做?

  2. 共享库如何工作?即创建库时将给出库中将给出加载和运行函数的地址。应用程序(main())如何解析要执行库函数的地址?

  3. 静态库是如何工作的,即在使用静态库的情况下如何进行地址说明和解析?


阅读 452

收藏
2020-06-07

共1个答案

一尘不染

这是在Linux上的工作方式:

1)不,您不需要做任何事情。但是,您可以使用gcc -fvisibility命令行参数限制导出变量,并使用可见性属性显式标记导出的条目。

2)可执行文件将包含其导入的所有功能的表(这些功能均具有默认可见性)。加载程序/链接程序将在运行之前选择一个地址来将库加载到该表并填充该表,对这些函数的调用是间接调用。(请注意,这也适用于共享对象)

3)静态链接是在链接时(在编译后)执行的。实际地址在程序集中被替换,它们是直接调用。

注意:有一个叫做PIC(位置无关代码)的东西。AFAIK,它处理在同一个共享库中对数据/函数的引用,因此链接器在加载库时不必覆盖库的一半代码,因为该代码不会对其库进行任何绝对引用自己的数据。您可以尝试尝试一下。

2020-06-07