Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic stack frame size support #274

Merged
merged 1 commit into from
Mar 25, 2022

Conversation

alessandrod
Copy link

@alessandrod alessandrod commented Feb 23, 2022

This PR implements dynamic stack frames, which can be enabled setting config.dynamic_stack_frames = true.

When using dynamic stack frames, r11 is exposed as the stack pointer. The stack is fully descending, so sub r11, N can be used to grow it, and add r11, N to shrink it. Those instructions are special cased by the interpreter and jit to resize the stack. No other operations are allowed on the stack register.

The stack pointer is allowed to overflow. In real programs, it's almost impossible to overflow since programs are metered and we enforce a max call depth. In fringe programs that (intentionally?) do overflow, EbpfError::AccessViolation is returned by MemoryRegion::map() once the overflown stack pointer is accessed. I opted for this since I think it's the best tradeoff for jitted programs (the BPF stack is separate from the jit stack so overflows won't mess with the jit), but happy to do explicit overflow checking if anyone feels strongly about this (although I'm not sure what the benefit would be).

At the moment config.max_call_depth is still enforced regardless of whether fixed or dynamic frames are in use, we might want to change that.

Dynamic frames are turned on if the input ELF is flagged as EF_SBF_V2 (see anza-xyz/llvm-project#26) and config.dynamic_stack_frames=true. Which means that a feature gate can be used in the monorepo to set dynamic_stack_frames=false to disable the feature entirely.

I've added tests which should cover all changes, and the rustc library/core tests pass with both fixed and dynamic frames.

@alessandrod alessandrod force-pushed the dynamic-stack branch 7 times, most recently from 70d0e1f to 01d13ed Compare February 24, 2022 00:25
@alessandrod alessandrod changed the title Initial dynamic stack frame size support Dynamic stack frame size support Feb 24, 2022
@alessandrod alessandrod force-pushed the dynamic-stack branch 3 times, most recently from 5ae3815 to 87b6f05 Compare March 1, 2022 02:30
@alessandrod alessandrod marked this pull request as ready for review March 1, 2022 02:46
@dmakarov
Copy link
Collaborator

dmakarov commented Mar 4, 2022

solana-labs/solana#20323

This change implements dynamic stack frames when config.dynamic_stack_frames is
set to true.

When dynamic_stack_frames=true, r11 is exposed as the stack pointer. The stack is
fully descending, so `sub r11, N` can be used to grow it, and `add r11, N` to
shrink it. Those are the only operations allowed on r11, which are special cased
by the interpreter and jit to resize the stack. No other operations are allowed
on the stack register.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants