简体   繁体   English

编辑中间程序集文件后重新链接

[英]Relink after editing intermediate assembly files

We can pass a flag to Cargo that is in turn passed to rustc to emit intermediate assembly files for the whole contents of a crate:我们可以将一个标志传递给 Cargo,该标志又传递给rustc以发出一个板条箱的全部内容的中间汇编文件:

$ RUSTFLAGS="--emit=asm" cargo rustc --release

After running this, indeed we can see a whole lot of .s files under target/$TARGET/release :运行之后,我们确实可以在target/$TARGET/release下看到一大堆.s文件:

$ ls target/avr-atmega32u4/release/deps/*.{s,elf}
target/avr-atmega32u4/release/deps/avr_config-e311e93c086c3db0.s
target/avr-atmega32u4/release/deps/avr_delay-157ca9fb1a916f1a.s
target/avr-atmega32u4/release/deps/avr_progmem-9dc1e040eb728712.s
target/avr-atmega32u4/release/deps/avr_std_stub-c3510b4296c6559e.s
target/avr-atmega32u4/release/deps/cfg_if-21f3790d6886cc57.s
target/avr-atmega32u4/release/deps/compiler_builtins-d2b51c47ad38c941.s
target/avr-atmega32u4/release/deps/core-195cf775332e0617.s
target/avr-atmega32u4/release/deps/ruduino-15843435a02e3c3a.s
target/avr-atmega32u4/release/deps/rustc_std_workspace_core-7426025ff9d9438f.s
target/avr-atmega32u4/release/deps/ufmt-b3d2cb48639acfb8.s
target/avr-atmega32u4/release/deps/ufmt_write-4e35e82da143e2d5.s
target/avr-atmega32u4/release/deps/worduino_avr-b35d7970ef451ba9.elf*
target/avr-atmega32u4/release/deps/worduino_avr-b35d7970ef451ba9.s
target/avr-atmega32u4/release/deps/worduino_engine-1dc7446bd9d04ccf.s

How do I change some of these and then continue with the same assembly and linking process?我如何更改其中的一些,然后继续相同的组装和链接过程? So let's say I edit the file target/avr-atmega32u4/release/deps/worduino_engine-1dc7446bd9d04ccf.s , how do I then ask Cargo to create a new version of worduino_avr-b35d7970ef451ba9.elf with otherwise the same link-time settings as the original invocation of cargo rustc ?假设我编辑文件target/avr-atmega32u4/release/deps/worduino_engine-1dc7446bd9d04ccf.s ,然后我如何要求 Cargo 创建一个新版本的worduino_avr-b35d7970ef451ba9.elf ,否则链接时间设置与cargo rustc的原始调用?

To my surprise, it turns out, at least for AVR, the assembly code corresponding to the toplevel crate contains everything needed, no linking required.令我惊讶的是,事实证明,至少对于 AVR,对应于顶层板条箱的汇编代码包含了所有需要的东西,不需要链接。 So for eg LLVM intermediate files, we can use llc for static compilation, and then GCC for trivial linking:因此,对于 LLVM 中间文件,我们可以使用llc进行 static 编译,然后使用 GCC 进行简单链接:

$ RUSTFLAGS="--emit=llvm-bc" cargo rustc --release
$ llc-15 -march=avr -mcpu=atmega32u4 -filetype=obj --function-sections target/avr-atmega32u4/release/deps/worduino_avr-b35d7970ef451ba9.bc -o foo.o
$ avr-gcc -mmcu=atmega32u4 -Os foo.o -o foo.elf

This produces a valid ELF file in foo.elf , however, it is not exactly the same as the one produced by Rust, which is concerning:这会在foo.elf中生成一个有效的 ELF 文件,但是,它与 Rust 生成的文件并不完全相同,后者涉及:

$ md5sum foo.elf target/avr-atmega32u4/release/deps/worduino_avr-b35d7970ef451ba9.elf
5ba0a483b6adbc81faaba180e8e5ad1c  foo.elf
198eff7c052172bcff6a9a81306a7bf7  target/avr-atmega32u4/release/deps/worduino_avr-b35d7970ef451ba9.elf

This seems to be because foo.o itself doesn't exactly match the intermediate object file worduino_avr-b35d7970ef451ba9.worduino_avr.124c28c8-cgu.0.rcgu.o created by Rust;这似乎是因为foo.o本身与worduino_avr-b35d7970ef451ba9.worduino_avr.124c28c8-cgu.0.rcgu.o不完全匹配; I'm not sure what exactly is going on here.我不确定这里到底发生了什么。

Functionally, loading the resulting .elf file into an AVR simulator, it seems that the result matches the behaviour of the real Rust output, so that's good.从功能上讲,将生成的.elf文件加载到 AVR 模拟器中,结果似乎与真实 Rust output 的行为相匹配,所以很好。 Still, it would be better if we could replicate the .elf file exactly.尽管如此,如果我们能够准确地复制.elf文件会更好。

Anyway, moving on the next question is how to do the same, but from assembly .s files instead of .bc .无论如何,继续下一个问题是如何做同样的事情,但是从程序集.s文件而不是.bc We should be able to replace llc with llvm-mc in the above pipeline:我们应该能够在上面的管道中用llvm-mc替换llc

$ RUSTFLAGS="--emit=asm" cargo rustc --release
$ llvm-mc-15 --arch=avr --mcpu=atmega32u4 -filetype=obj target/avr-atmega32u4/release/deps/worduino_avr-b35d7970ef451ba9.s -filetype=obj -o bar.o
$ avr-gcc -mmcu=atmega32u4 -Os bar.o -o bar.elf

However, here we hit another problem where llvm-mc mis-assembles the file .然而,在这里我们遇到了另一个问题,即llvm-mc错误组装文件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM