那里的连接器专家的问题。我一直在Matlab中处理mex文件,并且遇到了很多无法解释的崩溃,所以我想更深入一点。

您能否向我解释在加载(卸载)动态模块时如何在进程的虚拟内存空间中分配(取消分配)静态数据?

我假设这发生在_init()_fini()函数中。但是,是否在堆空间中为BSS段分配了一块内存以及其他动态内存分配?

那么动态模块中的全局数据呢?符号名称是否与主要可执行文件冲突?

感谢您就这些问题发表看法。如果我必须选择一个平台,那么我想听听ELF专家的意见,因为我在Linux上进行了大部分开发工作。

最佳答案



这部分很简单:每个ELF文件都有PT_LOAD段,您可以在readelf -Wl foo.so的输出中看到这些段。加载共享库时,这些段中的每一个都被mmap编码到地址空间中,并且充当该共享库中任何静态数据的“分配”。

卸载foo.so时,将通过munmap系统调用处理数据(和代码)。



这种假设是不正确的。 _init_fini是关于动态初始化的(例如,带有非平凡的构造函数/析构函数的C++中的类类型的全局变量)。到_init被调用时,所有全局变量的内存已经通过mmap“保留”了。


.bss节包含在与其他初始化(可写)数据相同的PT_LOAD段中。这就是为什么p_filesz中有单独的p_memszElfXX_Phdr的原因:p_filesz“覆盖”初始化的数据,(更大)的p_memsz导致mmap为初始化和.bss数据“分配”空间。



那呢我在上面介绍了初始化数据。



当然。您可以在int foo = 42;中定义a.out,在int foo = 24;中定义foo.so。通常的规则是,如果fooa.out的动态符号表中可见,那么无论从何处引用该foo,都将使用该a.out

foo不导出-rdymamic(如果它未与foo.so链接且未针对foo.so链接)时,或者当-Bsymbolic与ojit_code链接时,会出现复杂问题。

08-04 05:42
查看更多