c - .o 文件中的内存共享

标签 c memory compiler-construction linker

假设我有一个 A.c 文件并将其编译为 A.o 文件。 A.c文件如下:

int a;
void add(void)
{
}

A.o 文件与B.o 一起组成一个1.exe 文件。 A.o 文件与 C.o 一起组成一个 2.exe 文件。

我的问题是如果同时运行1.exe2.exea的地址这两个.exe文件的add()是一样的吗?换句话说,内存中有两个A.o还是只有一个?

最佳答案

您的内存中没有任何重定位的目标文件。

我猜你有一个 Linux 系统。如果在 Windows 上,原理保持不变,但细节有所不同。

链接器(调用以构建 1.exe2.exe)构建一个可执行文件 ELF文件(由多个段组成,特别是所谓的 "text" segment 用于机器代码和只读常量数据,以及 "data" segment 用于可变数据)。 execve(2)启动该程序的系统调用是内存映射 ELF 文件的几个段(几乎与某些 mmap(2) 系统调用一样)。

请注意,为 Linux 可执行文件使用 .exe 文件后缀是令人困惑且不常见的。按照惯例,Linux 可执行文件根本没有后缀,并且以小写字母开头。

链接器已将两个 A.o 文件复制并重新定位到不同的地方(因为 relocation )。所以经常会出现1.exe2.exea或者add的地址不一样的情况,处理它们的机器指令也是如此。

每个process有自己的address space (可以使用例如 mmap(2) 系统调用进行更改)。键入 cat/proc/1234/maps 以了解 pid 1234 进程的地址空间。也可以尝试 cat/proc/self/maps 以获取进程的地址空间运行那个 cat

如果不是 A.o 对象,您有一个共享对象(或动态库)libA.so 它的一些(mmap -ed) 段将被共享(其他人将使用 copy on write 技术),并且一些重定位发生在动态链接时(例如,如果它是一个插件,则在 dlopen 期间)。

另请阅读 Levine's book on Linkers and Loaders .

关于c - .o 文件中的内存共享,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16052022/

相关文章:

c - 如何长期正确维护一个监听端口?

windows - Perl 脚本如何知道它自己的内存占用?

compiler-construction - Haskell 编译器如何处理 'where' 语句?

html - 解析 HTML 表单数据

c - 如何从C中的 float 中提取小数部分?

c++ - 将 C++ 本地字符串返回给另一个函数

c++ - 同步访问变量

python - __decorated__ 用于 python 装饰器

macos - MacOSX 10.6 上的 getline 崩溃 C 编译器?

c - 编写我的第一个 C 程序,我无法克服这个愚蠢的错误