gpt4 book ai didi

c++ - 包含在 Linux GCC 链接器中

转载 作者:IT王子 更新时间:2023-10-29 01:00:47 30 4
gpt4 key购买 nike

我不明白 GCC 在 Linux 下是如何工作的。在源文件中,当我执行以下操作时:

#include <math.h>

编译器是提取适当的二进制代码并将其插入到已编译的可执行文件中,还是编译器插入对外部二进制文件(a-la Windows DLL?)的引用

我想这个问题的通用版本是:是否有与 *nix 下的 Windows DLL 等效的概念?

最佳答案

嗯。当您包含 math.h 时,编译器将读取包含可以使用的函数和宏声明的文件。如果您调用在该文件中声明的函数(header),那么编译器会在您的目标文件中的那个位置插入一条调用指令,该指令将从您编译的文件中生成(我们称它为 test.c 和创建的目标文件 test.o)。它还在该目标文件的重定位表中添加了一个条目:

Relocation section '.rel.text' at offset 0x308 contains 1 entries:
Offset Info Type Sym.Value Sym. Name
0000001c 00000902 R_386_PC32 00000000 bar

这将是功能栏的重定位条目。将在符号表中创建一个条目,指出该函数尚未定义:

9: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND bar

当您将 test.o 目标文件链接到程序中时,您需要链接名为 libm.so 的数学库。 so 扩展类似于 Windows 的 .dll 扩展。这意味着它是一个共享对象文件。编译器在链接时,将修复 test.o 的重定位表中出现的所有位置,将其条目替换为 bar 函数的正确地址。根据您使用的是库的共享版本还是静态版本(然后称为 libm.a),编译器将在编译后或稍后在您实际运行时进行修复启动你的程序。完成后,它将在该程序所需的共享库表中注入(inject)一个条目。 (可以用 readelf -d ./test 显示):

Dynamic section at offset 0x498 contains 22 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libm.so.6]
0x00000001 (NEEDED) Shared library: [libc.so.6]
... ... ...

现在,如果您启动程序,动态链接器将查找该库,并将该库链接到您的可执行镜像。在 Linux 中,执行此操作的程序称为 ld.so。静态库在动态部分没有位置,因为它们只是链接到其他目标文件,然后就被遗忘了;从那时起它们就是可执行文件的一部分。

实际上它实际上要复杂得多,我也不详细了解这一点。不过,这是粗略的计划。

关于c++ - 包含在 Linux GCC 链接器中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/332554/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com