Adds zero-cost stack overflow protection to your embedded programs

Overview

flip-link

adds zero-cost stack overflow protection to your embedded programs

The problem

Bare metal Rust programs may not be memory safe in presence of stack overflows. For example, this is the case for Rust programs based on v0.6.x of the cortex-m-rt crate.

The following program, which contains no unsafe code block, can run into undefined behavior if it reaches a stack overflow condition.

// static variables placed in the .bss / .data sections
static FLAG1: AtomicBool = AtomicU32::new(false); // .bss
static FLAG2: AtomicBool = AtomicU32::new(true);  // .data

fn main() {
    let _x = fib(100);
}

#[inline(never)]
fn fib(n: u32) -> u32 {
    // allocate and initialize 4 kilobytes of stack memory
    let _use_stack = [0xAA; 1024];

    if n < 2 {
        1
    } else {
        fib(n - 1) + fib(n - 2) // recursion
    }
}

#[interrupt]
fn interrupt_handler() {
    // does some operation with `FLAG1` and `FLAG2`
}

The default memory layout of ARM Cortex-M programs in RAM is shown below.

left: default memory layout of ARM Cortex-M programs; right: stack overflow condition

The function call stack, also known as the "stack", grows downwards on function calls and when local variables (e.g. let x) are created (these variables are also placed on the stack).

If the stack grows too large it collides with the .bss + .data region, which contains all the program's static variables. The collision results in the static variables being overwritten with unrelated data. This can result in the program observing the static variables in an invalid state: for example an AtomicBool may hold the value 3 -- this is undefined behavior because the Rust ABI expects this single-byte variable to be either 0 or 1.

The solution

One potential solution is to change the memory layout of the program and place the stack below the .bss+.data region.

With this flipped memory layout (pictured below) the stack cannot collide with the static variables. Instead it will collide with the boundary of the physical RAM memory region. In the ARM Cortex-M architecture, trying to read or write past the boundaries of the RAM region produces a "hardware exception". The cortex-m-rt crate provides an API to handle this condition: a HardFault exception handler can be defined; this "handler" (function) will be executed when the invalid memory operation is attempted.

left: flipped memory layout; right: stack overflow condition

flip-link implements this stack overflow solution. Linking your program with flip-link produces the flipped memory layout, which is memory safe in presence of stack overflows.

Architecture support

flip-link is known to work with ARM Cortex-M programs that link to version 0.6.x of the cortex-m-rt crate and are linked using the linker shipped with the Rust toolchain (LLD). At this time, it hasn't been tested with other architectures or runtime crates.

Installation

flip-link is available on crates.io. To install it, run

$ cargo install flip-link

Usage

Change the linker from rust-lld (the default) to flip-link in .cargo/config.toml

[target.'cfg(all(target_arch = "arm", target_os = "none"))']
# (..)
rustflags = [
  "-C", "linker=flip-link", # <- add this
  # (..)
]

NOTE that if you were using GNU ld or GNU gcc to link your program then this won't work. Support for other linkers is being tracked in issue #1.

Testing

Our CI enforces various checks. You can run them locally to make sure your PR will pass the CI:

  • cargo fmt --all -- --check
  • cargo clippy -- --deny warnings
  • cargo xtest
    • This installs the current revision of flip-link and runs cargo test.

Support

flip-link is part of the Knurling project, Ferrous Systems' effort at improving tooling used to develop for embedded systems.

If you think that our work is useful, consider sponsoring it via GitHub Sponsors.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be licensed as above, without any additional terms or conditions.

Comments
  • Drop `anyhow`

    Drop `anyhow`

    We don't use most of the features of anyhow here, so I've replaced it with just Box<dyn Error>.

    This does require some unfortunate duplication of the Result<T> alias.

    opened by jonas-schievink 6
  • flip-link error

    flip-link error

    windows os: 11 I use https://github.com/knurling-rs/app-template generate project add

    cortex-m-rtic = { version = "1.1.3" }
    
    error: linking with `flip-link` failed: exit code: 1
      |
      = note: "flip-link" "-flavor" "gnu" "C:\\Users\\zhaobo\\AppData\\Local\\Temp\\rustck3K05Z\\symbols.o" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\main-11049d013bb1904c.main.2fc7ea03-cgu.0.rcgu.o" "--as-needed" "-L" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps" "-L" "D:\\projects\\embeed\\app\\target\\debug\\deps" "-L" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\build\\cortex-m-5817308009678109\\out" "-L" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\build\\cortex-m-rt-4199a1caeb388d95\\out" "-L" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\build\\defmt-d86b0063a8a3b56a\\out" "-L" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\build\\stm32f1-14b8b2830e44275e\\out" "-L" "D:\\software\\rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\thumbv7m-none-eabi\\lib" "-Bstatic" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libstm32f1xx_hal-8051c863c3ad98b5.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libfugit_timer-fe7d59127748e96a.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libbxcan-e9e7ad35b16a23e4.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libstm32_usbd-ed785f6b86adbff3.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libusb_device-a233a87681d50602.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libfugit-6c4bc25732b1db27.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libgcd-4197544a75179d12.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libembedded_dma-d8fa02c1119216ed.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libstm32f1-b31ddd66260981cf.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libcortex_m_rt-c1a6a9ab4f0cfe1e.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\librtic-34882a4391d40282.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libheapless-3a2e6cf7174401b1.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libstable_deref_trait-b94e8061351ccd46.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libhash32-2ef9212d208b60d7.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libbyteorder-90345a976a4d83d8.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libbare_metal-7b4e9559ea5371a8.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\librtic_monotonic-8232f0df63c185a6.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\librtic_core-fbd27b968ff823cf.rlib" "--start-group" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libpanic_probe-a9b08e11c9fb609a.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libdefmt-d4cf8a2ca51cf9ce.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libbitflags-5351597746fc1950.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libcortex_m-f44fc0a28245896b.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libembedded_hal-0f940bf2e1d93e1f.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libvoid-b7e1daec3a29df70.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libnb-9a0f1077e9087fcc.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libnb-89e12803df9a6252.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libvolatile_register-1ef2fbeaac4c48e3.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libvcell-894f713cc598d2e9.rlib" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\libbare_metal-392c59e661be3df0.rlib" "D:\\software\\rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\thumbv7m-none-eabi\\lib\\librustc_std_workspace_core-d708ca894357bb88.rlib" "D:\\software\\rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\thumbv7m-none-eabi\\lib\\libcore-7279b5ba9f24caff.rlib" "--end-group" "D:\\software\\rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\thumbv7m-none-eabi\\lib\\libcompiler_builtins-25380e8375a00138.rlib" "-Bdynamic" "--eh-frame-hdr" "-znoexecstack" "-L" "D:\\software\\rustup\\toolchains\\stable-x86_64-pc-windows-msvc\\lib\\rustlib\\thumbv7m-none-eabi\\lib" "-o" "D:\\projects\\embeed\\app\\target\\thumbv7m-none-eabi\\debug\\deps\\main-11049d013bb1904c" "--gc-sections" "-O1" "-Tlink.x" "-Tdefmt.x" "--nmagic"
      = note: rust-lld: error: undefined symbol: _defmt_acquire
              >>> referenced by mod.rs:55 (D:\software\cargo\registry\src\rsproxy.cn-8f6827c7555bfaf8\defmt-0.3.2\src\export\mod.rs:55)
              >>>               panic_probe-a9b08e11c9fb609a.panic_probe.02df55b0-cgu.0.rcgu.o:(rust_begin_unwind) in archive D:\projects\embeed\app\target\thumbv7m-none-eabi\debug\deps\libpanic_probe-a9b08e11c9fb609a.rlib
              
              rust-lld: error: undefined symbol: _defmt_release
              >>> referenced by mod.rs:71 (D:\software\cargo\registry\src\rsproxy.cn-8f6827c7555bfaf8\defmt-0.3.2\src\export\mod.rs:71)
              >>>               panic_probe-a9b08e11c9fb609a.panic_probe.02df55b0-cgu.0.rcgu.o:(rust_begin_unwind) in archive D:\projects\embeed\app\target\thumbv7m-none-eabi\debug\deps\libpanic_probe-a9b08e11c9fb609a.rlib
              
              rust-lld: error: undefined symbol: _defmt_write
              >>> referenced by mod.rs:85 (src\export\mod.rs:85)
              >>>               defmt-d4cf8a2ca51cf9ce.defmt.d14e61bb-cgu.0.rcgu.o:(_$LT$$RF$mut$u20$W$u20$as$u20$core..fmt..Write$GT$::write_char::hbf1e7cda46151703) in archive D:\projects\embeed\app\target\thumbv7m-none-eabi\debug\deps\libdefmt-d4cf8a2ca51cf9ce.rlib
              >>> referenced by mod.rs:85 (src\export\mod.rs:85)
              >>>               defmt-d4cf8a2ca51cf9ce.defmt.d14e61bb-cgu.0.rcgu.o:(_$LT$$RF$mut$u20$W$u20$as$u20$core..fmt..Write$GT$::write_str::h9be493d4997977cf) in archive D:\projects\embeed\app\target\thumbv7m-none-eabi\debug\deps\libdefmt-d4cf8a2ca51cf9ce.rlib
              >>> referenced by mod.rs:85 (src\export\mod.rs:85)
              >>>               defmt-d4cf8a2ca51cf9ce.defmt.d14e61bb-cgu.0.rcgu.o:(defmt::export::istr::hf51bfc040acfc767) in archive D:\projects\embeed\app\target\thumbv7m-none-eabi\debug\deps\libdefmt-d4cf8a2ca51cf9ce.rlib
              >>> referenced 2 more times
              
              flip-link: the native linker failed to link the program normally; please check your project configuration and linker scripts
              
    
    warning: `app` (bin "main") generated 3 warnings
    error: could not compile `app` due to previous error; 3 warnings emitted
    
    
    opened by adminSxs 5
  • New release?

    New release?

    There's been substantial improvement over the past 5 months since the last crates.io release. We're using the latest on master for SoloKeys with no issue, but can't make use of the 5 month old release.

    Thank you for this awesome tool!

    type: question dificulty: easy 
    opened by conorpp 5
  • unbreak nightlies

    unbreak nightlies

    Our nightlies are failing: https://github.com/knurling-rs/flip-link/actions because our app-template patch doesn't apply anymore.This will likely break every time we update the app-template.. maybe we can come up with a less brittle way to modify the TODOs in the template?

    type: bug good first issue 
    opened by Lotterleben 5
  • Avoid the `tempfile` dependency

    Avoid the `tempfile` dependency

    tempfile pulls in an amazing number of dependencies, which we don't really need just for storing a single linker script.

    Note that I wasn't able to properly test this because the flip-link testsuite doesn't seem to work.

    opened by jonas-schievink 4
  • Add support for section length arithmetic using + sign as used in stm32f7xx-hal crate.

    Add support for section length arithmetic using + sign as used in stm32f7xx-hal crate.

    This change adds support for defining the RAM region's length as 10K + 10M. This type of notation is used in the stm32f7xx-hal crate and flip-link failed with the message MEMORY.RAM found after scanning linker scripts which was also fixed to add the missing not.

    opened by matoushybl 4
  • flip-link does not respect `memory.x` overrides

    flip-link does not respect `memory.x` overrides

    Steps to reproduce

    1. Instantiate the app-template for the nRF52840 (add nrf52840-hal as a dependency).

    2. Create a memory.x override

    $ # run hal crate build script -> puts memory.x in target
    $ cargo check --lib
    
    $ cp `fd memory.x target` .
    
    $ # halve the amount of RAM
    $ $EDIT memory.x
    $ bat memory.x
    MEMORY
    {
      FLASH : ORIGIN = 0x00000000, LENGTH = 1024K
      RAM : ORIGIN = 0x20000000, LENGTH = 128K
    }
    
    1. Inspect produced binaries
    $ # `touch` = force relinking; or use `cargo clean`
    $ touch src/bin/hello.rs
    $ cargo size --bin hello -- -A -x
    hello  :
    section                size         addr
    .vector_table         0x100          0x0
    .text                0x145c        0x100
    .rodata               0x4ac       0x155c
    .data                  0x30   0x2003fbc8
    .bss                    0x8   0x2003fbf8
    .uninit               0x400   0x2003fc00
    
    $ cargo nm --bin hello -- --demangle --numeric-sort | rg stack
    2003fbc8 A _stack_start
    

    Both binary tools indicate that flip-link thinks the RAM size is 256 KiB (0x4_0000) even though the memory.x override indicates 128 KiB

    1. Compare against rust-lld (disable flip-link)
    $ $EDIT .cargo/config.toml
    $ bat .cargo/config.toml
    [target.'cfg(all(target_arch = "arm", target_os = "none"))']
    runner = "probe-run --chip nrf52840"
    rustflags = [
      # "-C", "linker=flip-link", # <- disabled
      "-C", "link-arg=-Tlink.x",
      "-C", "link-arg=-Tdefmt.x",
      "-C", "link-arg=--nmagic",
    ]
    
    $ cargo size --bin hello -- -A -x
    hello  :
    section                size         addr
    .vector_table         0x100          0x0
    .text                0x145c        0x100
    .rodata               0x4ac       0x155c
    .data                  0x30   0x20000000
    .bss                    0x8   0x20000030
    .uninit               0x400   0x20000038
    
    $ cargo nm --bin hello -- --demangle --numeric-sort | rg stack
    20020000 A _stack_start
    

    rust-lld respects the memory.x override and uses 128 KiB as the size of the RAM region

    Meta

    flip-link version

    $ cargo install --list | rg ^flip-link
    flip-link v0.1.4:
    
    type: bug dificulty: easy status: needs PR priority: high 
    opened by japaric 3
  • Add structopt

    Add structopt

    This PR introduces sctructopt for handling cli-params.

    • I tried to use argument names and descriptions like GNU ld
    • using structopt enables us to drop fn get_output_path(...) and dramatically shorten fn get_linker_scripts(...)
    opened by Urhengulas 3
  • Problem with memory.x in the project root

    Problem with memory.x in the project root

    When the linker script with RAM location is in the root directory where you invoke cargo it is always used by the linker. So only the beginning of the stack is changed which leads to an invalid memory layout.

    When you look at the man page for GNU ld it says for the -T option:

    If scriptfile does not exist in the current directory, "ld" looks for it in the directories specified by any preceding -L options.

    So it seems that this is also valid for included scripts.

    As a first attempt to fix this problem I set the working dir for the second linker invocation to the temp dir containing the modified script. This works for my setup where I have a memory.x in the project root as well as for the example app in this repository.

    It could be a problem though when you have multiple linker scripts in project root. But maybe you could set the project root as additional -L directory. What do you think?

    opened by DerFetzer 3
  • ci: cache cargo registry & build artifacts

    ci: cache cargo registry & build artifacts

    time savings on cache hit

    | Job | before | after | after/before | |-----------------|--------|-------|--------------| | ubuntu-stable | 105s | 37s | 35% | | macos-stable | 132s | 68s | 51% | | windows-stable | 176s | 98s | 55% | | ubuntu-nightly | 92s | 40s | 43% | | macos-nightly | 127s | 65s | 51% | | windows-nightly | 163s | 103s | 63% |

    don't ask me how to replicate the caching steps into the non-matrix job without copy-pasting the whole thing because I don't know :P

    opened by japaric 2
  • search linker scripts in cwd first

    search linker scripts in cwd first

    harmonize linker script directory search order with non-flip-link linkers to reduce surprises. Specifically, other crates might introduce spurious and potentially wrong memory.x scripts, this PR attempts to do some damage control by searching the current working directory first

    opened by spookyvision 2
  • We are on vacation ⛄

    We are on vacation ⛄

    Dear Knurling-rs community,

    Most of us maintainers of Knurling-rs will be on vacation from this week until the beginning of January. Therefore please do not expect too much activity in our repositories and issue tracker.

    We wish you a great holiday season (if you have it) or, otherwise, just a good time.

    Best, your Knurling-rs team ❄️

    opened by Urhengulas 0
  • Adding tests to flip-link

    Adding tests to flip-link

    rust-lld is a linker for GNU files. (call with rust-lld -flavor gnu -T memory.x) flip-link should accept the same files as rust-lld. Currently, some memory.x files (describing the memory) are not accepted by flip-link while being accepted by rust-lld.

    We added in total 7 tests to manage input that is currently accepted by rust lld. We cherry-picked the first commit of this PR, adding additions on ORIGIN, and made a different PR ħere.

    The tests are passing but there are changes left to do:

    • for now the find_ram_in_linker_script performs a for loop to find the right line for the variable RAM that we need in order to write in the original linker script, then do various regex operations to parse the line properly. This needs to be handled more elegantly.

    • incorrect units must be handled properly (for example, RAM : ORIGIN = 0x20000000, LENGTH = 64P should return Err), we wrote a test for that but it is commented atm:

    • abbreviations (ORIGIN|o|org) should be accepted

    Lots to do, so please advise 😄

    opened by Dajamante 0
  • consider rejecting negative lengths

    consider rejecting negative lengths

    rust-lld will happily link memory.x files that contain lines like these

    RAM : ORIGIN = 0x20020000, LENGTH = 1K - 2K
    

    or even

    RAM : ORIGIN = 0x20020000, LENGTH = -1K
    

    it seems the behavior is that the value overflows because linking works even if .bss is 1MiB in size.

    we could either reject these indicating that there may be a problem in the linker script or that negative lengths are not supported.

    if we want to support them then I'm not sure what flip-link behavior should be. transforming either of the above to

    RAM : ORIGIN = 0x20020000 - 1K, LENGTH = 1K
    

    does not produce the same binary with a single linker pass

    status: needs design 
    opened by japaric 2
  • subtraction is handled incorrectly

    subtraction is handled incorrectly

    given this line in the MEMORY command:

      RAM : ORIGIN = 0x20020000, LENGTH = 2K - 1K
    

    flip-link internally computes the length as 2048 instead of as 1024

    type: bug 
    opened by japaric 0
  • Does not work with `alloc-cortex-m`

    Does not work with `alloc-cortex-m`

    When I try to use alloc-cortex-m in the following fashion:

    #![no_main]
    #![no_std]
    #![feature(alloc_error_handler)]
    
    extern crate alloc;
    
    use alloc_cortex_m::CortexMHeap;
    use core::alloc::Layout;
    use defmt::*;
    
    #[global_allocator]
    static ALLOCATOR: CortexMHeap = CortexMHeap::empty();
    
    #[cortex_m_rt::entry]
    fn main() -> ! {
        defmt::timestamp!("{=usize}", now());
    
        info!("initializing heap");
    
        let start = cortex_m_rt::heap_start() as usize;
        let size = 4;
        debug!("start = {:#010x}, size = {:#010x}", start, size);
    
        unsafe { ALLOCATOR.init(start, size) }
    
       // other code
    }
    

    Then the program panics immediately upon trying to initialize the heap, and the heap start address appears to be wrong (I am using the STM32F411, so SRAM begins at 0x2000 0000 and ends at 0x2002 0000).

        Finished dev [unoptimized + debuginfo] target(s) in 3.78s
         Running `probe-run --chip STM32F411VETx target/thumbv7em-none-eabihf/debug/tasks`
    (HOST) INFO  flashing program (49 pages / 49.00 KiB)
    (HOST) INFO  success!
    ────────────────────────────────────────────────────────────────────────────────
    0 INFO  initializing heap
    └─ tasks::__cortex_m_rt_main::_ @ src/bin/tasks.rs:28
    0 DEBUG start = 0x2001fffc, size = 0x00000004
    └─ tasks::__cortex_m_rt_main::_ @ src/bin/tasks.rs:33
    ────────────────────────────────────────────────────────────────────────────────
    stack backtrace:
       0: HardFaultTrampoline
          <exception entry>
       1: linked_list_allocator::hole::HoleList::new
            at /home/ibiyemi/.cargo/registry/src/github.com-1ecc6299db9ec823/linked_list_allocator-0.8.11/src/hole.rs:50:9
       2: linked_list_allocator::Heap::init
            at /home/ibiyemi/.cargo/registry/src/github.com-1ecc6299db9ec823/linked_list_allocator-0.8.11/src/lib.rs:73:22
       3: alloc_cortex_m::CortexMHeap::init::{{closure}}
            at /home/ibiyemi/.cargo/registry/src/github.com-1ecc6299db9ec823/alloc-cortex-m-0.4.1/src/lib.rs:58:13
       4: cortex_m::interrupt::free
            at /home/ibiyemi/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.7.3/src/interrupt.rs:64:13
       5: alloc_cortex_m::CortexMHeap::init
            at /home/ibiyemi/.cargo/registry/src/github.com-1ecc6299db9ec823/alloc-cortex-m-0.4.1/src/lib.rs:57:9
       6: tasks::__cortex_m_rt_main
            at src/bin/tasks.rs:35:14
       7: main
            at src/bin/tasks.rs:24:1
       8: Reset
    (HOST) WARN  call stack was corrupted; unwinding could not be completed
    (HOST) ERROR the program panicked
    

    If I disable flip-link by commenting out "-C", "linker=flip-link" in .cargo/config.toml, then this panic does not happen, and a more reasonable start address is printed:

        Finished dev [unoptimized + debuginfo] target(s) in 52.83s
         Running `probe-run --chip STM32F411VETx target/thumbv7em-none-eabihf/debug/tasks`
    (HOST) INFO  flashing program (49 pages / 49.00 KiB)
    (HOST) INFO  success!
    ────────────────────────────────────────────────────────────────────────────────
    0 INFO  initializing heap
    └─ tasks::__cortex_m_rt_main::_ @ src/bin/tasks.rs:28
    0 DEBUG start = 0x20000454, size = 0x00010000
    └─ tasks::__cortex_m_rt_main::_ @ src/bin/tasks.rs:33
    

    It has occurred to me that the point of flip-link is to allow stack overflow errors to be caught by relying on the stack crashing into the RAM boundary. Does this mean that flip-link is incompatible with the use of a heap, or does the heap need to be placed above the stack in memory? If it's the latter, how would I achieve that?

    type: enhancement 
    opened by laptou 11
  • GHA support

    GHA support

    Is there a way to use flip-link in a Github Action, without building it from source every time?

    See https://github.com/Neotron-Compute/Neotron-BMC/runs/3152027601?check_suite_focus=true as an example.

    type: question 
    opened by thejpster 15
Releases(v0.1.5)
  • v0.1.5(Jan 24, 2022)

    What's Changed

    • Do linking test as part of cargo test; cleanup by @Urhengulas in https://github.com/knurling-rs/flip-link/pull/40
    • Verify initial stack-pointer to be inside static RAM by @Urhengulas in https://github.com/knurling-rs/flip-link/pull/41
    • xtest by @Urhengulas in https://github.com/knurling-rs/flip-link/pull/44
    • Cargo.toml: Disable default features of env_logger by @Urhengulas in https://github.com/knurling-rs/flip-link/pull/45
    • Tests for 22 by @Urhengulas in https://github.com/knurling-rs/flip-link/pull/42
    • Adds add for user survey into readme. by @BriocheBerlin in https://github.com/knurling-rs/flip-link/pull/46
    • Fix clippy warning by @justahero in https://github.com/knurling-rs/flip-link/pull/49
    • Update change log with latest entries by @justahero in https://github.com/knurling-rs/flip-link/pull/48
    • Removes call to fill in user survey from readme. by @BriocheBerlin in https://github.com/knurling-rs/flip-link/pull/50
    • xtest: Pass --force to cargo install by @Urhengulas in https://github.com/knurling-rs/flip-link/pull/52
    • Avoid the tempfile dependency by @jonas-schievink in https://github.com/knurling-rs/flip-link/pull/51
    • xtest: Clear test-flip-link-apps target/-fir before each run by @Urhengulas in https://github.com/knurling-rs/flip-link/pull/53
    • update & upgrade by @Urhengulas in https://github.com/knurling-rs/flip-link/pull/54
    • Drop anyhow by @jonas-schievink in https://github.com/knurling-rs/flip-link/pull/55
    • flip-link v0.1.5 by @Urhengulas in https://github.com/knurling-rs/flip-link/pull/56

    New Contributors

    • @BriocheBerlin made their first contribution in https://github.com/knurling-rs/flip-link/pull/46

    Full Changelog: https://github.com/knurling-rs/flip-link/compare/v0.1.4...v0.1.5

    Source code(tar.gz)
    Source code(zip)
  • v0.1.4(Jan 24, 2022)

    What's Changed

    • Publish v0.1.3 by @Urhengulas in https://github.com/knurling-rs/flip-link/pull/35
    • Bump object to 0.24.0 by @Urhengulas in https://github.com/knurling-rs/flip-link/pull/36
    • handle no units in linker script parser by @japaric in https://github.com/knurling-rs/flip-link/pull/38
    • flip-link v0.1.4 by @Urhengulas in https://github.com/knurling-rs/flip-link/pull/39

    Full Changelog: https://github.com/knurling-rs/flip-link/compare/v0.1.3...v0.1.4

    Source code(tar.gz)
    Source code(zip)
  • v0.1.3(Jan 24, 2022)

    What's Changed

    • README: explain stack overflow problem & solution by @japaric in https://github.com/knurling-rs/flip-link/pull/18
    • add white background to SVG images by @japaric in https://github.com/knurling-rs/flip-link/pull/20
    • README.md: fix typos by @Lotterleben in https://github.com/knurling-rs/flip-link/pull/21
    • Problem with memory.x in the project root by @DerFetzer in https://github.com/knurling-rs/flip-link/pull/22
    • Set bors up by @Urhengulas in https://github.com/knurling-rs/flip-link/pull/24
    • Simplify by @Urhengulas in https://github.com/knurling-rs/flip-link/pull/28
    • Simplify linker invocations + argument parsing + struct LinkerScript by @Urhengulas in https://github.com/knurling-rs/flip-link/pull/30
    • Minimize deps by @Urhengulas in https://github.com/knurling-rs/flip-link/pull/32
    • CI: add clippy by @Urhengulas in https://github.com/knurling-rs/flip-link/pull/33

    New Contributors

    • @DerFetzer made their first contribution in https://github.com/knurling-rs/flip-link/pull/22

    Full Changelog: https://github.com/knurling-rs/flip-link/compare/v0.1.2...v0.1.3

    Source code(tar.gz)
    Source code(zip)
  • v0.1.2(Jan 24, 2022)

  • v0.1.1(Jan 24, 2022)

    What's Changed

    • only run fmt on stable by @Lotterleben in https://github.com/knurling-rs/flip-link/pull/12
    • use cortex-m-quickstart to test that 'it links' by @japaric in https://github.com/knurling-rs/flip-link/pull/15
    • Add support for section length arithmetic using + sign as used in stm32f7xx-hal crate. by @matoushybl in https://github.com/knurling-rs/flip-link/pull/14
    • README: update knurling link to website by @Lotterleben in https://github.com/knurling-rs/flip-link/pull/16
    • fix parsing of attributes by ignoring them by @ain101 in https://github.com/knurling-rs/flip-link/pull/17

    New Contributors

    • @matoushybl made their first contribution in https://github.com/knurling-rs/flip-link/pull/14
    • @ain101 made their first contribution in https://github.com/knurling-rs/flip-link/pull/17

    Full Changelog: https://github.com/knurling-rs/flip-link/compare/v0.1.0...v0.1.1

    Source code(tar.gz)
    Source code(zip)
  • v0.1.0(Jan 24, 2022)

    What's Changed

    • add CI to build, check fmt and use in example app by @Lotterleben in https://github.com/knurling-rs/flip-link/pull/6
    • optimize CI by @Lotterleben in https://github.com/knurling-rs/flip-link/pull/8
    • README: add installation instructions by @Lotterleben in https://github.com/knurling-rs/flip-link/pull/9

    Full Changelog: https://github.com/knurling-rs/flip-link/commits/v0.1.0

    Source code(tar.gz)
    Source code(zip)
Owner
Knurling
Get a handle on bare metal Rust
Knurling
Cover your tracks during Linux Exploitation by leaving zero traces on system logs and filesystem timestamps. 👻🐚

moonwalk Cover your tracks during Linux Exploitation / Penetration Testing by leaving zero traces on system logs and filesystem timestamps. ?? Table o

Mufeed VH 1.1k Jan 6, 2023
Simple verification of Rust programs via functional purification in Lean 2(!)

electrolysis About A tool for formally verifying Rust programs by transpiling them into definitions in the Lean theorem prover. Masters thesis: Simple

Sebastian Ullrich 300 Dec 11, 2022
Rust-verification-tools - RVT is a collection of tools/libraries to support both static and dynamic verification of Rust programs.

Rust verification tools This is a collection of tools/libraries to support both static and dynamic verification of Rust programs. We see static verifi

null 253 Dec 31, 2022
Whole program static stack analysis

cargo-call-stack Static, whole program stack analysis Other examples: Embedded CoAP / IPv4 server (source) "Hello, world!" HEADS UP: This tool relies

Jorge Aparicio 457 Dec 22, 2022
A simple menu to keep all your most used one-liners and scripts in one place

Dama Desktop Agnostic Menu Aggregate This program aims to be a hackable, easy to use menu that can be paired to lightweight window managers in order t

null 47 Jul 23, 2022
spy on the DNS queries your computer is making

dnspeep dnspeep lets you spy on the DNS queries your computer is making. Here's some example output: $ sudo dnspeep query name

Julia Evans 1.2k Dec 29, 2022
Checks your files for existence of Unicode BIDI characters which can be misused for supply chain attacks. See CVE-2021-42574

BIDI Character Detector This tool checks your files for existence of Unicode BIDI characters which can be misused for supply chain attacks to mitigate

null 5 Aug 26, 2022
ripgrep recursively searches directories for a regex pattern while respecting your gitignore

ripgrep (rg) ripgrep is a line-oriented search tool that recursively searches the current directory for a regex pattern. By default, ripgrep will resp

Andrew Gallant 35k Dec 31, 2022
Advanced Fuzzing Library - Slot your Fuzzer together in Rust! Scales across cores and machines. For Windows, Android, MacOS, Linux, no_std, ...

LibAFL, the fuzzer library. Advanced Fuzzing Library - Slot your own fuzzers together and extend their features using Rust. LibAFL is written and main

Advanced Fuzzing League ++ 1.2k Jan 6, 2023
How-to: Sanitize your Rust code!

rust-san How-to: Sanitize your Rust code! Intro How to use the sanitizers? Examples AddressSanitizer Out of bounds access Use after free LeakSanitizer

Jorge Aparicio 359 Dec 22, 2022
Breaking your Rust code for fun and profit

Breaking your Rust code for fun & profit this is an architecture-preview, not all components are there This is a mutation testing framework for Rust c

null 542 Jan 4, 2023
A tiny program that locates and extracts public save files from Windows to your local directory!

Save Game Extractor | Download Save Game Extractor is a tool that automatically locates and copies save files for Windows games in public directories.

popcar2 6 Dec 23, 2021
Cyg will help you to secure files in your repository directly using PGP encryption

cyg: Secure files in your repository Cyg will help you to secure files in your repository directly using PGP encryption. The name "cyg" was inspired b

Hisam Fahri 2 Aug 31, 2022
Rust macro to make recursive function run on the heap (i.e. no stack overflow).

Decurse Example #[decurse::decurse] // ?? Slap this on your recursive function and stop worrying about stack overflow! fn factorial(x: u32) -> u32 {

Wisha W. 18 Dec 28, 2022
Zero-cost high-level lua 5.3 wrapper for Rust

td_rlua This library is a high-level binding for Lua 5.3. You don't have access to the Lua stack, all you can do is read/write variables (including ca

null 47 May 4, 2022
Zero-cost asynchronous programming in Rust

Zero-cost asynchronous programming in Rust Documentation | Website futures-rs is a library providing the foundations for asynchronous programming in R

The Rust Programming Language 4.7k Jan 1, 2023
zero runtime cost default arguments in rust

Default Arguments in Rust Enables default arguments in rust by macro in zero cost. Just wrap function with default_args! and macro with name of functi

Jaeyong Sung 73 Sep 6, 2022
Zero-cost and safe interface to UEFI firmware

ZFI – Zero-cost and safe interface to UEFI firmware ZFI is a Rust crate for writing a UEFI application with the following goals: Provides base APIs th

Ultima Microsystems 22 Sep 14, 2023
A Rust compiler plugin and support library to annotate overflow behavior

overflower This project contains a compiler plugin and supporting library to allow the programmer to annotate their code to declare how integer overfl

null 104 Nov 28, 2022
cargo extension for flashing embedded rust programs via dfu based on jacobrosenthals cargo-hf2

cargo-dfu This crate provides a cargo subcommand to flash ELF binaries via dfu Most STM chips will probably work with this, although you might need to

Roman Kretschmer 0 Feb 6, 2022