首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在c中,如何对其他文件中定义函数进行实际链接

在c中,如何对其他文件中定义函数进行实际链接
EN

Stack Overflow用户
提问于 2017-06-22 15:43:19
回答 1查看 62关注 0票数 0

我有两个文件

main.c:

代码语言:javascript
运行
复制
int main()
{
    func();
    return 0;
}

和第二个文件

func.c:

代码语言:javascript
运行
复制
#include <stdio.h>
void func()
{
    printf("welcome");
}

我想知道链接器是如何解析函数调用(func)的。我知道重定位是在重定位表的帮助下发生的,但我不能理解这究竟是如何发生的

EN

回答 1

Stack Overflow用户

发布于 2017-06-22 15:59:11

这就是声明的作用。考虑以下代码:

代码语言:javascript
运行
复制
extern void func(void);

int main(void)
{
     func(void);
     return 0;
}

当使用gcc -c main.c进行编译时,它将生成一个main.o对象文件,其中的主函数将如下所示:

代码语言:javascript
运行
复制
Disassembly of section .text:

0000000000000000 <main>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   e8 00 00 00 00          callq  9 <main+0x9>
   9:   b8 00 00 00 00          mov    $0x0,%eax
   e:   5d                      pop    %rbp
   f:   c3                      retq   

并且重定位表将包含一个条目:

代码语言:javascript
运行
复制
RELOCATION RECORDS FOR [.text]:
OFFSET           TYPE              VALUE 
0000000000000005 R_X86_64_PC32     func-0x0000000000000004

现在请注意,5main中的callq立即地址的精确偏移量(这并不是特别重要的编码方式,它可能会在不同的平台上甚至在一个平台内有所不同)。

无论如何,考虑到您在C代码中放置的func的外部声明,编译器知道它可能还没有合适的地址将函数放入callq中。

当链接器将不同的目标文件链接在一起时,它会确保所有这样的悬空地址都被成功解析。

现在回答您的特定问题-将重定位表项(外部声明)与实际符号(函数或变量定义)匹配的关键是它们的签名。特定签名产生可能匹配的这样的重定位条目和符号。不同的签名在链接方面本质上是不同的。

除了这一点,你的问题实际上是相当宽泛的。因此,请询问进一步的研究方向或使其更清楚。

编辑:还请注意,我是在x86_64 linux下获得这些清单的,您可能会在您的环境中得到不同的结果,但想法仍然是相同的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44693207

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档