How to let rustc compile functions with segmented stack?

Long time ago Rust used segmented stack (split stack), but switched to continuous stack around 2013. I am now working on ARM Cortex-M baremetal targets and trying to use segmented stack to prevent stack overflow. I would like to know how to let the current Rust compiler compile functions with segmented stack.

My understanding:

  • rustc needs to emit the LLVM attribute split-stack to the compiled functions.
  • Currently we have no rustc option that controls this behavior. Related discussion here.
  • I will need to modify the compiler source code to add the split-stack attribute to the generated LLVM IR.

What I have done:

  • Patched LLVM to emit the segmented stack function prologue for my embedded baremetal target.
  • Wrote a runtime to support __morestack call.
  • Tested the LLVM patch and the runtime implementation by some test code written in C compiled with Clang (with -fsplit-stack option turned on).
  • Built rustc from source with my patched LLVM and linked it to rustup toolchain.

It seems that the only missing piece in the puzzle is to let rustc emit the split-stack attribute. Could someone please point me to the source file that is responsible for picking LLVM attributes for functions? Thanks!

In case you don't get other responses, it will be inside here, although perhaps someone can tell you which file specifically: rust/compiler/rustc_codegen_llvm/src at master · rust-lang/rust · GitHub

1 Like

This might be relevant to your concerns: Zero cost stack overflow protection for ARM Cortex-M devices | Embedded in Rust

1 Like

Thanks! The TL;DR version of this stack overflow protection mechanism is to "place the .bss+.data section at the top of RAM and put the stack below it".

It assumes a single stack so we can have nothing else below it. In my case, I am trying to write an embedded OS, so there will be multiple stacks. Even if I put the stacks below all .bss+.data sections, they can still grow and clash into each other.

I am writing a general purposed OS, so I need to support multiple stacks. Under some restricted use case, we can get by with one stack on the whole system. DroneOS takes this approach.

Thank you. It seems I can add another call to llvm::CreateAttrString() in from_fn_attrs() to emit the split-stack attribute.

Update: the approach works well on x86_64 Linux.

Update2: now working for armv7em-none-eabi target.

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.