Closed
Description
STR
With LTO
$ git clone https://github.com/japaric/embedded-demo
$ cd embedded-demo
$ xargo rustc --release -v -- -C lto -Z print-link-args
error: linking with `arm-none-eabi-ld` failed: exit code: 1
|
= note: "arm-none-eabi-ld" (..)
= note: /home/japaric/tmp/cortex-m-quickstart/target/thumbv7m-none-eabi/release/deps/demo-cbfeda05d006136a.stm32f103xx0-3aeab9466184a3fc8b7128118183614f.rs.rcgu.o: In function `WWDG':
stm32f103xx0-3aeab9466184a3fc8b7128118183614f.rs:(.text+0x0): undefined reference to `DEFAULT_HANDLER'
Linker arguments:
"arm-none-eabi-ld"
"-L"
"/home/japaric/.xargo/lib/rustlib/thumbv7m-none-eabi/lib"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/deps/demo-cc40ab28f2256f87.aligned0-82013031e0adce00680863804baa6d8a.rs.rcgu.o"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/deps/demo-cc40ab28f2256f87.bare_metal0-808e09050a3d8f805631ff0277b6d5f4.rs.rcgu.o"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/deps/demo-cc40ab28f2256f87.core0-5fd795c6d6efb3b3ac7a93ecfc07e7e8.rs.rcgu.o"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/deps/demo-cc40ab28f2256f87.cortex_m0-eef2b118572823d6b94a55e824ed5889.rs.rcgu.o"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/deps/demo-cc40ab28f2256f87.cortex_m_rt0-a8ed1a542842e08c4e593519be42c026.rs.rcgu.o"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/deps/demo-cc40ab28f2256f87.demo0-bda6ff7720758957fa6c47e3e0108053.rs.rcgu.o"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/deps/demo-cc40ab28f2256f87.r00-d69ab77365edbeda5c83b8029590a7b6.rs.rcgu.o"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/deps/demo-cc40ab28f2256f87.stm32f103xx0-b5844958e960b076c42287432ab6341a.rs.rcgu.o"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/deps/demo-cc40ab28f2256f87.vcell0-17ed04a11350e05da18a7742432984b.rs.rcgu.o"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/deps/demo-cc40ab28f2256f87.volatile_register0-fb687636cdd4964c5e2d4a17ac1819ef.rs.rcgu.o"
"-o"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/deps/demo-cc40ab28f2256f87"
"--gc-sections"
"-L"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/deps"
"-L"
"/home/japaric/tmp/embedded-demo/target/release/deps"
"-L"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/build/cortex-m-rt-8aa404db3cc9f96b/out"
"-L"
"/home/japaric/.xargo/lib/rustlib/thumbv7m-none-eabi/lib"
"-Bstatic"
"/home/japaric/.xargo/lib/rustlib/thumbv7m-none-eabi/lib/libcompiler_builtins-e9756467978f74f8.rlib"
"-Tlink.x"
"-Bdynamic"
Without LTO
$ xargo rustc --release -- -Z print-link-args && echo OK
OK
Linker arguments:
"arm-none-eabi-ld"
"-L"
"/home/japaric/.xargo/lib/rustlib/thumbv7m-none-eabi/lib"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/deps/demo-7be3323439223b43.demo0.rcgu.o"
"-o"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/deps/demo-7be3323439223b43"
"--gc-sections"
"-L"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/deps"
"-L"
"/home/japaric/tmp/embedded-demo/target/release/deps"
"-L"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/build/cortex-m-rt-8aa404db3cc9f96b/out"
"-L"
"/home/japaric/.xargo/lib/rustlib/thumbv7m-none-eabi/lib"
"-Bstatic"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/deps/libstm32f103xx-0620e682f6df62cd.rlib"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/deps/libcortex_m_rt-637507d2b1db7555.rlib"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/deps/libr0-a7dcce0e9369941f.rlib"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/deps/libcortex_m-690455d6e615b2d4.rlib"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/deps/libvolatile_register-45547ab3b9a80964.rlib"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/deps/libvcell-89a145f57bb869ee.rlib"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/deps/libbare_metal-ddaad95c84c49e08.rlib"
"/home/japaric/tmp/embedded-demo/target/thumbv7m-none-eabi/release/deps/libaligned-61d763743c0a5839.rlib"
"/home/japaric/.xargo/lib/rustlib/thumbv7m-none-eabi/lib/libcore-2fea0bb2226aafe6.rlib"
"/home/japaric/.xargo/lib/rustlib/thumbv7m-none-eabi/lib/libcompiler_builtins-e9756467978f74f8.rlib"
"-Tlink.x"
"-Bdynamic"
Note the order in which objects (crates) are passed to the linker between an LTO and a non-LTO build. The LTO build more or less reverses the order.
stm32f103xx
has an undefined symbol, DEFAULT_HANDLER
, which is provided by its dependency cortex-m-rt
. The LTO build fails to link because cortex-m-rt
appears before stm32f103xx
in the list of linker arguments.
With the old, non-parallel LTO there was only a single object so there was no linking problem.
cc @alexcrichton Is there an option to get the old, non-parallel LTO on a recent nightly? I tried codegen-units = 1
and I still got parallel LTO.
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
alexcrichton commentedon Dec 6, 2017
@japaric still digesting, but
-Z thinlto=no
can turn off the parallel version on nightlyalexcrichton commentedon Dec 6, 2017
Hm ok this is surprising! I thought linkers didn't care about ordering of objects, just of libraries...
@japaric if you take the failing linker command line and use the
-Wl,-(
and-Wl,-)
(I think that's the syntax?) arguments around the object files (to tell the linker to consider them as a group) does that work? I also wouldn't be surprised if a symbol was accidentally stripped...japaric commentedon Dec 6, 2017
@alexcrichton
--start-group
/--end-group
(I'm usingld
, notgcc
) doesn't work. The symbol is in libcortex_m_rt.rcgu.o though but it became non-global (local?) for some reason:The symbol is global (but weak) in the rlib:
japaric commentedon Dec 6, 2017
It certainly matters, at least for static libraries.
.a
and.rlib
are just archives of objects (.o
).alexcrichton commentedon Dec 6, 2017
Ok interesting! I think that's the bug then (ThinLTO can be a little aggressive about internalizing by accident sometimes).
Do you think you'd be able to minimize this a bit to where it's just a symbol being internalized by accident by the LTO passes?
japaric commentedon Dec 6, 2017
@alexcrichton
linkage = "weak"
is required to trigger the problem. Repro below:japaric commentedon Dec 6, 2017
Removing
#[linkage = "weak"]
doesn't fix the problem I originally reported. Adding--start-group
/--end-group
to that still doesn't fix the problem:DEFAULT_HANDLER
is still non-global (internal) after parallel LTO.alexcrichton commentedon Dec 6, 2017
@japaric aha weak linkage would definitely do it! I was able to reproduce locally with weak linkage and then it was fixed with the weak linkage removed.
Although for you removing the weak linkage didn't fix it?
alexcrichton commentedon Dec 6, 2017
Oh I see, maybe there's two bugs at play then? Would it be possible to minimize with the weak linkage removed from the original case as well?
alexcrichton commentedon Dec 6, 2017
Ok the first test case reduced a bit is:
alexcrichton commentedon Dec 6, 2017
The
LLVMRustPrepareThinLTOResolveWeak
pass here is internalizingFOO
. I never did think that pass was correct... My guess is that there's probably some trickery which I didn't copy from LLVM correctly or needs to be tweaked.japaric commentedon Dec 6, 2017
If I make DEFAULT_HANDLER part of the public API (
pub
and visible/reachable) and remove weak linkage then it works / links. (It seems that weak linkage makes the symbol global even if it's not part of the public API.) I can live with the DEFAULT_HANDLER change (I candoc(hidden)
the function) but I can't drop the weak linkage because that's a feature.[-][regression] parallel LTO breaks linking because it reverses linker arguments[/-][+][regression] parallel LTO breaks linking because it internalizes weak symbols[/+]alexcrichton commentedon Dec 6, 2017
@japaric yeah makes total sense to me, the regression in handling of weak linkage is definitely a bug to fix!
I think the need for "make it all the way public" is because
#[linkage]
the attribute doesn't play that well into which symbols are exported and whatnot. I think this worked with LTO in one module because it happened to match up but with LTO in multiple modules the matchup isn't happening and the symbol is lost.I didn't spend too much time trying to rationalize
#[linkage]
(in general, not specifically weak) with ThinLTO as it's an unstable feature, but I'm always game for tweaks!7 remaining items