-
Notifications
You must be signed in to change notification settings - Fork 264
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
Add no_std compatibility #106
Conversation
Hi, and thanks! In the meantime, would you mind fixing the issue raised by the Appveyor workflow please (Windows)? Given that you use Could you please also sign-off your commits? |
Hi, thank you for looking into the PR. Please don't worry about the timeline / delays, I realise that it is a non-trivial change and requires time to actually look through all of this. I will look into the appveyor issue on windows and make sure it gets fixed. I will also start signing off the commits from now on. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apologies for the delay, I've kept this PR in a corner of my mind but struggled to find the time (and motivation) to dive into it.
Here are some elements of feedback, I see that the PR is indeed still in progress and needs some polishing. See also inline below.
We'd need specific jobs in the CI workflow as well, to make sure that we build both with and without the standard library to test your changes and detect regressions.
Hi, No worries about the delay, my goal with this PR was to contribute back a small subset of changes that I needed to introduce to I think compared to those changes, adding no_std support is potentially useful so I will continue working on this PR |
b320dfd
to
88e27cd
Compare
One note regarding your comment about asm_parser and disassembler being disabled: |
Ok I did some restructuring and now the import switching is done the same way serde does it. |
Can you please sign-off your commits? |
Re: signing off commits |
3807e34
to
17353e3
Compare
bf7ff28
to
a8447c9
Compare
1544093
to
ce48245
Compare
Ok @qmonnet I think the PR is in much better state now. Following your advice I have split my changes into two logical commits:
I have also tested that it builds correctly on an actual no_std target: STM32-f439zi running RIOT. I managed to flash this example program:
It looks like everything works in I can quickly publish a repo with the experimental setup that I used to test the new version of rbpf running without |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks much better, thanks! Some comments here and there.
Please clean up the commit log from your second commit, you have multiple sign-off tags (likely because you squashed commits together and kept the descriptions of all commits). |
dd333b4
to
da48944
Compare
Thanks a lot! Sorry I didn't have the time to review last night, I'll do it soon. |
No worries at all, take your time. No need to rush, I realise it is quite a big change in terms of files affected (not that big functionality-wise). Thank you for your time and guidance with the PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for your work!
I've got some comments, and I think I'm a bit confused as to when the assembler is supported without std
. I probably need to take some time to play with your code and check why rbpf complains if I try to enable the tests; in the meantime, I commented at the locations where it is not clear to me.
The required changes are mostly minor things, we're getting closer!
Regarding the formatting of your patches, I'd recommend the following:
- Squash the fixes from the last commit into the relevant earlier commits
- Rework your commit descriptions, in particular for the second commit. What's interesting in this description is not so much to describe the changes (and not the history of the different changes and fixes incorporated during the review); instead, it should provide the motivation for the change, and explain what the commit addresses, what difficulties arose and how the commit works around them, etc. Everything related to the context of the change.
205f395
to
9b6eb04
Compare
Ok thank you for the review and your suggestions. I will rework the commit messages and squash the subsequent fixes.
The last commit fixing pipeline warnings will be split and squashed into the above commits where the changes belong appropriately |
6e1fe11
to
f357b45
Compare
This was done to prepare the foundation for adding no_std compatibility. The std feature can be disabled by the users of this library which will compile rbpf in a way that doesn't require the standard library. Signed-off-by: SzymonKubica <[email protected]>
543b0e0
to
1897181
Compare
This commit introduces a lib module in `lib.rs` responsible for reexporting all imports from the standard library used by the crate. It also adjusts all dependencies of rbpf so that they depend on the standard library only if the `std` feature is used. This was done to make rbpf compatible with `no_std`. This compatibility is needed to run rbpf on embedded devices where the standard library isn't available. Main difficulties: - println! macro isn't available on `no_std`. A workaround was introduced to use the `log` crate and call logging macros such as `warn!` or `info!` in places where println is used when we have access to the standard library. Users of the crate can then define their custom logger elsewhere in the code and thanks to the log crate it will be called by rbpf and print messages using the provided implementation. - the VM interpreter depends on std::io::Error and std::io::ErrorKind. Those structs aren't available on no_std. We introduce a simple implementation of these two which exposes the same API and use it under `no_std` as a drop-in replacement. An important note is that the original ErrorKind enum has more than 40 available entries whereas our implemnentation only provides the one that is currently used throughout the rbpf code (ErrorKind:Other). Should a dependency on new variants be added in the future, the replacement ErrorKind (found in no_std_error.rs) would have to be updated to maintain compatibility. The reason we don't include all variants right now is that not all of those error kinds are meaningful in `no_std` context. - the assembler and asm_parser depend on `combine` crate and use the EasyParser from there by default. The problem is that the EasyParser is not available in no_std. We get around this issue by using the regular Parser when std is not available. Note that the difference between the two parser implementations is the quality of error messages. The EasyParser is able to extract much more information and report it in an error. The regular one simply returns "invalid parse". Because of this, two tests of the assembler needed to be updated to conditionally check for different error messages when running with/without std. Signed-off-by: SzymonKubica <[email protected]>
1897181
to
81b0dd8
Compare
Ok I think everything has been cleaned up now. Thank you very much for all of your feedback and time spent reviewing my changes. Now all imports / dependency changes are in the second commit. I managed to find some additional assembler tests that could be reenabled (tests/misc.rs). I think it helps a lot to see all changes in a single logical commit |
@qmonnet could you please approve the CI workflow run? Don't worry about reviewing the changes today, no need to rush. I just wanted to make sure that rearranging the changes didn't produce any new pipeline warnings. Enjoy your weekend and feel free to look into the PR when you are free. |
Hi @qmonnet, thank you for triggering the workload, seems like the pipeline passes successfully and no new warnings emitted. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apologies once again for the delay. I do realise this is not a great way to keep you motivated for this PR, and I'm sorry for the poor contribution experience in terms of delays. Thanks a lot for bearing with me.
And thanks for this work, this is in a very nice shape now! I think there's just a small fix to do in the README, but everything else looks good as far as I can tell. Well done, and nice work on the commit description for your second commit! ❤️
Added a new entry in the ToC for 'build features'. A description of the `no_std` feature was added there. Signed-off-by: SzymonKubica <[email protected]>
Signed-off-by: SzymonKubica <[email protected]>
81b0dd8
to
e494650
Compare
Ok @qmonnet, thank you for pointing out the issue it the README, it is fixed now. Thank you for picking up on it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, thanks a lot for this work!
Perfect, thank you for approving the PR 🚀 |
Congrats on getting your µBPF paper into the ACM workshop! 🎉 |
Thank you! |
What was added?
Added support for rbpf to run on
no_std
environments.Why is it needed?
Using rbpf on targets without
std
support increases compatibility of the crate.I've been using a modified version of rbpf to run eBPF programs on microcontrollers (see [here(https://github.com/SzymonKubica/mibpf))
Testing
Currently the code builds successfuly with both configuration options enabled, i.e. all build configurations succeed:
All tests (except for the ones using the
print
- only available in std) pass in both configuration options.TODO items for the PR
no_std
on an example embedded deviceNotes
The structure of
std
/no_std
feature-gating is inspired byserde
, inside oflib.rs
a public module:lib
is defined and itcontains reexports of all required items from std/alloc/core. It is then used throughout the codebase by importing all items
declared inside of it:
This behaves similarly as if we were using the standard library as we don't have to import things like
String
orVec
manually.