我有一个适用于Nordic nRF52832 BLE微控制器的现有C固件。我想链接一些我在Rust中编写的新代码。
当我尝试这样做时,链接器会抱怨我对堆栈有两个不同的定义:
/nix/store/m7gf0nzixwgqk21an0fxc047qa0mvbng-gcc-arm-embedded-7-2018-q2-update/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/bin/ld: .stack_dummy has both ordered [`.stack_sizes' in /home/matthias/source/tbconnect/modem/target/thumbv7em-none-eabihf/release/libtbmodem.a(alloc-314aba8dbd2706e9.alloc.deuukmti-cgu.0.rcgu.o)] and unordered [`.stack' in .sdk/modules/nrfx/mdk/gcc_startup_nrf52.o] sections
我想这里的重要部分是链接器告诉我,SDK Nordic为BLE微控制器提供了.stack_dummy
,Rust库提供了自己的堆栈定义。
实际上,我希望编译为库的代码不会提供堆栈的定义。如果所有库都定义了堆栈,我该如何将多个库链接到项目中?我对这个假设完全错误吗?
所以我想知道我对Rust库的定义是否完全错误。
Cargo.toml:
[package]
name = "tbmodem"
version = "0.1.0"
edition = "2018"
publish = false
[lib]
crate-type = ["staticlib"]
[profile.dev]
panic = "abort"
[profile.release]
panic = "abort"
[dev-dependencies]
timebomb = "0.1.2"
然后使用cargo build --release --target thumbv7em-none-eabihf
答案 0 :(得分:2)
在计算堆栈大小时,GCC和LLVM之间似乎不兼容。
.stack_sizes
部分包含LLVM堆栈元数据:llc -stack-size-section
option。这些似乎是函数指针和大小对,其顺序与.text
部分相同(因此,错误消息中的ordered
也是如此)。
在我发现的一个GCC链接程序脚本中(在Debian Stretch中,/usr/share/doc/gcc-arm-none-eabi/examples/ldscripts/gcc.ld
看起来可能有所不同)
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
因此,GCC使用具有所需堆栈大小的伪段,并且将它们以任意顺序放在.stack_dummy
中应该会产生所需的总堆栈大小。因为.stack_sizes
与*(.stack*)
匹配,所以GCC链接器尝试将LLVM节放在.stack_dummy
中,但是失败。
因此,您可以尝试在Rust中禁用-stack-size-section
,或修改链接器文件。