在ELF(可执行和可链接格式)文件生成中使用avr-gcc和avr-ld的区别

问题描述 投票:0回答:1

抱歉,如果这可能偏离主题。
在使用avr-gcc或avr-ld生成.hex(Intel HEX格式)文件的过程中,输出(最终结果)有显着不同。作为最低限度的澄清,我讨论的是在生成对象文件之后生成 ELF 文件的步骤。

在我的第一次尝试中,我使用

avr-ld
来生成我的 ELF 文件。过程运行顺利,但在生成 HEX 文件并上传到我的主板后,它没有执行任何操作(如上传空白 HEX 文件)。

在第二次尝试时,我遵循了此处的建议:

链接时指定MCU类型很重要。编译器使用 -mmcu 选项来选择链接在一起的启动文件和运行时库。如果未指定此选项,编译器将默认使用 8515 处理器环境,这肯定是您不想要的。

果然如我所料。上传了十六进制文件,我的主板也相应更新了。

所以我的问题如下:

  1. 为什么链接器 (
    avr-ld
    ) 丢失了我正在使用的微控制器的信息。我以为MCU信息存储在Object文件中。
  2. 这个配置背后的逻辑是什么?我的思维方式是否错误(使用
    avr-gcc
    编译/生成 .o 文件,
    avr-ld
    链接 .o 文件并生成 EFL 文件,以及
    avr-objcopy
    仅删除有用信息并更改文件的格式)文件 ELF -> HEX)?
  3. 有什么方法可以使用
    avr-ld
    实现与使用
    avr-gcc
    生成 ELF 文件时相同的输出吗?
c gcc linker microcontroller avr
1个回答
1
投票
  1. 为什么链接器(avr-ld)丢失了我正在使用的微控制器的信息。我以为MCU信息存储在Object文件中。

链接器不会丢失该信息,它从一开始就没有提供过。 对象文件分别ELF 标头处于“模拟”级别,即像

-mmcu=arch
这样的粒度,其中
arch
avr2
avr25
avrxmega2
avrtiny
等之一。

  1. 使用
    avr-gcc
    编译/生成.o文件,
    avr-ld
    链接.o文件并生成ELF文件,
    avr-objcopy
    仅删除有用信息并更改文件ELF→HEX的格式?

avr-gcc
不是编译器,它只是一个驱动程序,根据提供的文件类型和选项调用其他程序,如编译器本身
cc1
cc1plus
、汇编器
as
、链接器
ld
。 驱动程序将为这些程序添加选项,这大大简化了它们的使用,其中许多选项在
specs-attiny25
中进行了描述(从 v5 开始)。

作为示例,采用一个简单的

main.c
,其主函数返回 0,并使用

对其进行处理

avr-gcc main.c -o main.elf -mmcu=attiny25 -save-temps -v -Wl,-v

-v
使驱动程序显示它正在发出的命令,
-save-temps
存储中间文件,例如汇编。 对于 avr-gcc v8.5,链接过程从调用
collect2
:

开始
.../bin/../libexec/gcc/avr/8.5.0/collect2 -plugin .../bin/../libexec/gcc/avr/8.5.0/liblto_plugin.so -plugin-opt=.../bin/../libexec/gcc/avr/8.5.0/lto-wrapper -plugin-opt=-fresolution=main.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lm -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lattiny25 -mavr25 -o main.elf .../bin/../lib/gcc/avr/8.5.0/../../../../avr/lib/avr25/tiny-stack/crtattiny25.o -L.../bin/../lib/gcc/avr/8.5.0/avr25/tiny-stack -L.../bin/../lib/gcc/avr/8.5.0/../../../../avr/lib/avr25/tiny-stack -L.../bin/../lib/gcc/avr/8.5.0 -L.../bin/../lib/gcc -L.../bin/../lib/gcc/avr/8.5.0/../../../../avr/lib main.o -v --start-group -lgcc -lm -lc -lattiny25 --end-group

其中

...
代表安装工具的绝对路径。正如您所看到的,驱动程序添加了一些盐,例如它链接到启动代码
crtattiny25.o
、标准库,如
libc.a
libm.a
libgcc.a
collect2
收集构建启动代码所需的一些额外信息,然后回调编译器1,最后
ld

提供给

ld
的选项看起来非常类似于提供给
collect2
的选项。唯一特定于设备的东西是:启动代码
crtattiny25.o
和设备库
libattiny25.a
。 许多其他特定于设备的内容已经编译到代码中,例如 SFR 地址、
#ifdef __AVR_ATtiny25__
等。

  1. 有什么方法可以使用
    avr-ld
    实现与使用
    avr-gcc
    生成 ELF 文件时相同的输出吗?

您可以手动提供所有这些选项。 尽管 在几乎所有情况下,您都希望使用

avr-gcc
进行链接,以便所有这些血淋淋的选项都是正确且完整的。


1

-flto
起,LTO(链接时优化)需要回调编译器。 链接器调用一个插件,该插件使用 LTO 字节码调用编译器,将其编译为使用 LTO 编译器
lto1
进行汇编,然后是
as
,然后是
ld
。 该工具的新版本在没有 lto 编译时始终使用链接器插件;可以
-fno-use-linker-plugin
这使得调用链和选项更加简单。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.