加载程序如何从动态模块

时间:2016-03-30 18:11:10

标签: c++ linker loader mex elf

那里的链接大师的问题。我一直在使用Matlab中的mex文件,并且已经收到了大量无法解释的崩溃,所以我想深入挖掘一下。

您可以向我解释当加载(卸载)动态模块时,如何在进程的虚拟内存空间中分配(解除分配)静态数据?

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

动态模块中的全局数据怎么样?是否有可能与主要可执行文件发生符号名称冲突?

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

1 个答案:

答案 0 :(得分:2)

  

您能解释一下在加载(卸载)动态模块时,如何在进程的虚拟内存空间中分配(解除分配)静态数据吗?

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

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

  

我认为这发生在_init()和_fini()函数

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

  

然而,BSS段

.bss部分包含在其他初始化(可写)数据所在的PT_LOAD段中。这就是为什么p_filesz中有一个单独的p_memszElfXX_Phdrp_filesz“涵盖”初始化数据,而(更大)p_memsz导致mmap {1}}为初始化和.bss数据“分配”空间。

  

动态模块中的全局数据怎么样?

怎么样?我在上面介绍了初始化数据。

  

是否有可能与主要可执行文件发生符号名称冲突?

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

a.out未导出foo时(如果它未与-rdymamic 相关联且未与foo.so相关联),就会出现并发症,或foo.so-Bsymbolic链接时。