Создание статической библиотеки с помощью Rust, чтобы связать ее с прошивкой кода C arm-none-eabi - PullRequest
1 голос
/ 04 апреля 2019

У меня есть прошивка C для микроконтроллера Nordic nRF52832 BLE.Я хотел бы связать с ним новый код, написанный на 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 есть .stack_dummy для микроконтроллера BLE, а библиотека 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

1 Ответ

2 голосов
/ 05 апреля 2019

Это выглядит как несовместимость между GCC и LLVM при вычислении размеров стека.

Раздел .stack_sizes содержит метаданные стека LLVM: llc -stack-size-section опция .Похоже, это пары указателей и размеров функций в том же порядке, что и секции .text (отсюда ordered в сообщении об ошибке).

В скрипте компоновщика GCC я нахожу (/usr/share/doc/gcc-arm-none-eabi/examples/ldscripts/gcc.ld вDebian stretch, ваш может выглядеть или не выглядеть по-разному):

    /* .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, но это не удается.

Таким образом, вы можете попытаться отключить -stack-size-section в Rust или изменить компоновщикфайл.

...