First program linking issues
Hi,
I am following the Copper book, and I am currently having problems with the very first program (http://japaric.github.io/copper/first/build.html).
The program compiles, but the objdump output is the following:
$arm-none-eabi-objdump -CD target/thumbv7m-none-eabi/debug/app
target/thumbv7m-none-eabi/debug/app: file format elf32-littlearm
Disassembly of section .text:
00000000 <_reset-0x8>:
0: 20010000 andcs r0, r1, r0
4: 00000009 andeq r0, r0, r9
For some reason the main function is optimized away at some point.
If I make rustc emit the assembly file, I can see the function is there, with the right symbol (_reset), so I guess that the problem comes while linking.
@yuri91 are you using a mac? Does the gcc you are using come from the gcc-arm-embedded tap/cask? Someone reported (japaric/discovery#34) that that gcc has some bug like the one you reported here. Could you try the gcc from the px4/px4 tap? (Sorry, I don't have the exact instructions to do that as I don't access to a mac)
I am not using a mac, I am using Arch Linux. The version of arm-none-eabi-gcc that I had installed from the community repo was 6.3. I looked the version currently shipped with Ubuntu, and it is 4.8 or 4.9. So I tried the 4.9 myself, and It works. Thank you very much for your help, I didn't think it could be an actual bug in the linker.
Also, I looked into the other two related issues (japaric/discovery#34 and japaric/f3/issues/75), and I think that they have a 6.x version of GCC too.
I'm using Arch as well with gcc 6.3 but I can't repro your problem. I get:
$ arm-none-eabi-objdump -Cd target/thumbv7m-none-eabi/debug/bar
target/thumbv7m-none-eabi/debug/bar: file format elf32-littlearm
Disassembly of section .text:
00000000 <_reset-0x8>:
0: 20010000 .word 0x20010000
4: 00000009 .word 0x00000009
00000008 <_reset>:
8: b083 sub sp, #12
a: e7ff b.n c <_reset+0x4>
c: 202a movs r0, #42 ; 0x2a
e: 9001 str r0, [sp, #4]
10: 9000 str r0, [sp, #0]
12: e7ff b.n 14 <_reset+0xc>
14: e7fe b.n 14 <_reset+0xc>
Does changing the loop in main to
loop {
unsafe {
::core::ptr::read_volatile(0x0 as *const u32);
}
}
makes the linker preserve the _reset symbol? With gcc 6.3 I mean. There's a LLVM bug when you have loops without side effects but that's supposed to only occur when optimizations (+LTO) are enabled. Which is not the case here but just to discard the possibility.
Ok, my bad:
I was actually using yet another version of GCC (6.2.1) from the AUR. Back when I installed that package (probably a year ago or so) there wasn't the one in [community] yet. So the actual package in [community] with GCC 6.3 works, like the 4.9 one.
Good to know it's solved. I'll add a note to the book suggesting trying a different linker if you get a binary that's too different from what's in the book.
Hi,
I had the same issue with gcc 4.9. It seems to come from the fact that the entry point has the same name as the variable _reset you define in the ld script. here is 2 ways to fix it:
- use KEEP(*(.text._reset)) or a better alternative
- rename your entry point to _start or something else (both in the ld script and the main.rs) or rename the _reset variable in the ld script
Hope it helps
I am also experiencing this issue on arch. I'm using
arm-none-eabi-gccfrom community ( 6.3.1 20170330)- xargo 0.3.6
- rustc 1.18.0-nightly (7627e3d31 2017-04-16)
and compiling in 02-hardware with xargo build --target thumbv7em-none-eabihf --verbose which produces this binary: https://oolong.tahnok.me/cdn/app
I cloned this repo, so the code should be correct. Tried changing the entry point and changing the loop to that unsafe read_volatile, but same output.
The copper book is pretty outdated at this point and won't have time to update in the short term. You are better off starting with this blog post.