gpt4 book ai didi

c - 可执行和可链接格式(.elf)和对象(.o)文件之间的区别

转载 作者:太空宇宙 更新时间:2023-11-04 03:14:34 24 4
gpt4 key购买 nike

我在 linux 上的 gcc 手册 (man gcc) 中查找 -c 选项 (gcc -c infile)状态:

-c: Compile or assemble the source files, but do not link. The linking stage simply is not done. The ultimate output is in the form of an object file for each source file.
By default, the object file name for a source file is made by replacing the suffix .c, .i, .s, etc., with .o.

更重要的是,在检查 ELF 文件和目标文件(使用 file 命令)时,输出是相同的:

file ./out/main.o: ELF 32-bit LSB relocatable, Atmel AVR 8-bit, version 1 (SYSV), not stripped
file ./out/main.elf: ELF 32-bit LSB executable, Atmel AVR 8-bit, version 1 (SYSV), statically linked, not stripped

所以他们都有相同的描述。我的问题是:

  • 这两个文件之间的实际区别是什么,或者如果我有多个源文件?
  • 要运行的正确文件是什么,如何生成它?
  • 我需要目标文件,还是它们只是中间文件?
  • 如果我使用 -c 选项和一些标志(-Wall -g -std=c99 -Os)编译一些源文件并从中获取目标文件,这些标志是否会在 ELF 文件生成时持续存在(如果我在对象文件上使用它们,我可以在生成 ELF 文件时跳过这些标志吗)?

最佳答案

让我们举一个简单的例子。你有三个文件:

cnt.h

void inc_counter();
void print_counter();

cnt.c

#include <stdio.h>
#include <cnt.h>

static int counter= 0;

void inc_counter() {
couner++;
}

void print_counter() {
printf("Counter: %d\n", counter);
}

ma​​in.c

#include <counter.h>

int main(char** args) {
inc_counter();
print_counter();
return 0;
}

然后编译 cnt.cmain.c 以创建 cnt.omain.o .

  • cnt.o 将包含 get_counterinc_counter 的可执行代码。对于每个它都有一个入口点。但代码不可执行。 printf 的调用将不起作用,因为 printf 的地址尚不清楚。因此该文件包含稍后需要修复的信息。
  • main.o 将包含 main 的可执行代码及其入口点。同样,inc_counterprint_counter 的引用将不起作用。

在第二步中,文件cnt.omain.o 和标准C 库将被链接并创建一个可执行输出文件(带有.elf 或无扩展名)。链接器将在 inc_counter 调用和函数 inc_counter 之间创建缺失的链接。它会对 print_counterprintf 做同样的事情,从而包括来自标准库的 printf 的代码。

因此,虽然这两种文件类型主要由可执行代码组成,但 .o 文件仅包含代码片段,而 .elf 文件包含完整的程序。

注意:当您创建或使用动态链接库时,还有其他变化。但为了简单起见,我将它们排除在外。

关于c - 可执行和可链接格式(.elf)和对象(.o)文件之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53210259/

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