Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upLLD support (AKA LLD *almost* works out of the box) #53
Comments
This comment has been minimized.
This comment has been minimized.
|
update: Once PR rust-lang/rust#48125 lands a standalone LLD (version 6.0) binary will ship with the Rust distribution on some (all?) tier 1 platforms. We'll be able to use that lld to link ARM Cortex-M binaries so we should revisit this issue after that PR lands. |
This comment has been minimized.
This comment has been minimized.
|
Update: LLD is now being shipped with the Rust toolchain. You'll need Xargo v0.3.11 to be able to use it though. I was testing this again and had to patch things a bit more after #43 landed: diff --git a/link.x b/link.x
index 6f39655..64bf73b 100644
--- a/link.x
+++ b/link.x
@@ -56,11 +56,11 @@ SECTIONS
/* its zero sized */
_sstack = _stack_start < ORIGIN(RAM)? _stack_start : ORIGIN(RAM);
- /* fictitious region that represents the memory available for the stack */
- .stack _sstack (INFO) : ALIGN(4)
- {
- . += (_estack - _sstack);
- }
+ /* /\* fictitious region that represents the memory available for the stack *\/ */
+ /* .stack _sstack (INFO) : ALIGN(4) */
+ /* { */
+ /* . += (_estack - _sstack); */
+ /* } */
PROVIDE(_sbss = ORIGIN(RAM));
.bss _sbss : ALIGN(4)
@@ -84,11 +84,11 @@ SECTIONS
_sheap = _edata;
_eheap = _sheap + _heap_size;
- /* fictitious region that represents the memory available for the heap */
- .heap _sheap (INFO) : ALIGN(4)
- {
- . += _heap_size;
- }
+ /* /\* fictitious region that represents the memory available for the heap *\/ */
+ /* .heap _sheap (INFO) : ALIGN(4) */
+ /* { */
+ /* . += _heap_size; */
+ /* } */
/* fake output .got section */
/* Dynamic relocations are unsupported. This section is only used to detect
@@ -114,9 +114,9 @@ SECTIONS
/* a rustc hack will force the program to read the first byte of this section,
so we'll set the (fake) start address of this section to something we're
sure can be read at runtime: the start of the .text section */
- .debug_gdb_scripts _stext (INFO) : {
+ .debug_gdb_scripts _stext (NOLOAD) : {
KEEP(*(.debug_gdb_scripts))
- }
+ } > FLASH
/DISCARD/ :
{(This actually breaks cortex-m-rt-ld but it doesn't matter right now as I'm just testing LLD) It seems to me that LLD is producing bad binaries in some cases: when flashing the allocator example from cortex-m-quickstart v0.2.5 I get a segfault in OpenOCD: $ # compiled using the LLD in $(rustc --print sysroot)
$ arm-none-eabi-gdb -q target/thumbv7m-none-eabi/debug/app
Reading symbols from target/thumbv7m-none-eabi/debug/app...done.
(gdb) target remote :3333
Remote debugging using :3333
0xfffffffe in ?? ()
(gdb) load
Loading section .vector_table, size 0x400 lma 0x8000000
Loading section .text, size 0x60ea lma 0x8000400
Loading section .rodata, size 0x1804 lma 0x80064f0
Loading section .data, size 0x10 lma 0x8007cee
Remote connection closed$ openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg
(..)
Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : accepting 'gdb' connection on tcp/3333
Info : device id = 0x20036410
Info : flash size = 64kbytes
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc
Info : Padding image section 0 with 6 bytes
[1] 3342 segmentation fault (core dumped) openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfgI was wondering if this was a bug in the LLD version shipped with the toolchain so I tried a more recent version and I got this error: $ ld.lld --version
LLD 7.0.0 (git://github.com/llvm-mirror/lld.git bceb08ce5f0055cee953673a3e098fef868a18d4) (compatible with GNU linkers)
$ xargo build
error: linking with `ld.lld` failed: exit code: 1
|
= note: "ld.lld" "-L" (..)
= note: ld.lld: error: section .rodata load address range overlaps with .data
>>> .rodata range is [0x80064F0, 0x8007CF3]
>>> .data range is [0x8007CEE, 0x8007CFD]which I don't understand because the program does fit in Flash memory -- GNU LD can link it within the memory constraints. So I went back to inspect the binary linked using rustc's LLD (version 6.0). $ arm-none-eabi-size -Ax target/thumbv7m-none-eabi/debug/app | grep rodata
.rodata 0x1804 0x80064f0
$ arm-none-eabi-nm -C target/thumbv7m-none-eabi/debug/app | grep sidata
08007cee A _sidataThis shows that indeed So it seems that LLD is not ready for prime time yet. It would be great to report this issue or see if it has already been reported in LLVM's bug tracker. Unfortunately, I won't have time to follow up on that. |
This was referenced Mar 9, 2018
This comment has been minimized.
This comment has been minimized.
|
Turns out the overlap problem I mentioned above also occurs with GNU LD in some scenarios (I don't know the exact cause). However, #63 fixes the issue for both LD and LLD. Will re-test LLD in a bit. |
japaric
added a commit
that referenced
this issue
Apr 6, 2018
japaric
closed this
in
401416a
Apr 9, 2018
This comment has been minimized.
This comment has been minimized.
|
I'm still seeing the overlap problem when there is static data. I was able to reproduce using cortex-m-quickstart with the following changes: .cargo/config
Cargo.toml
examples/minimal.rs
So .rodata is [0x800007a0, 0x800007a4] and .data starts at [0x080007a2]. Looking at the symbol table in detail:
The last function in .text is [0x08000790, 0x0800079e] (core::cell::UnsafeCell::get())
The first (and only) entry in .data is
which presumably is being loaded from [0x0800079e, 0x080007a2] if _sidata So it looks like lld is not respecting the .rodata alignment when writing out the initializer. |
This comment has been minimized.
This comment has been minimized.
|
This appears to be fixed in the latest LLD ( $ arm-none-eabi-size -Ax target/thumbv7em-none-eabihf/debug/app | grep rodata
.rodata 0x4 0x80007a0
$ arm-none-eabi-nm -C target/thumbv7em-none-eabihf/debug/app | grep sidata
080007a4 A _sidata(with rustc LLD I get We probably only have to backport the fix. |
japaric commentedJan 17, 2018
If you switch the linker from arm-none-eabi-ld to ld.lld you'll get the following error:
But if you modify this crate link.x like this:
/* a rustc hack will force the program to read the first byte of this section, so we'll set the (fake) start address of this section to something we're sure can be read at runtime: the start of the .text section */ - .debug_gdb_scripts _stext (INFO) : { + .debug_gdb_scripts _stext (NOLOAD) : { KEEP(*(.debug_gdb_scripts)) - } + } > FLASHPrograms link correctly. The resulting binaries are well formed and debug information works.🎉
However, this results in an artifical increase of size of the text section as reported by
arm-none-eabi-size:This is just an error in the report though. The .debug_gdb_scripts doesn't end up in FLASH even with the linker script changes.
This issue is to gauge interested in adding LLD support right now (by applying the above diff).
Alternatively we can hold off until LLD lands in rustc (hopefully sometime this year) since it's only then when we'll be able to drop the dependency on a external linker (arm-none-eabi-ld).