-
Notifications
You must be signed in to change notification settings - Fork 465
Support Rust core::fmt::Argument
in vsprintf
#280
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
Conversation
This comment has been minimized.
This comment has been minimized.
Why |
Both |
Hmm... A new one would allow us to have a little less changes on the C side (at least slightly simpler ones). Even a rare symbol could be used instead of a letter, since users in the C side should never use it on their own. Something that needs escaping like |
I think the C changes are small enough to not affect our decision. If we do this, we should also add a check in |
People may use symbol after a regular
If we want to prevent people from using it from C, I can just remove the change I made to |
What about the octal/hex escape sequence idea? (I added it to the comment after posting, sorry)
+1 I would do that, yeah -- nevertheless, having a more specific error (e.g. "the format specifier exists, but should not be used from C") would be best (but please do not do that part, that way we have one more "good first issue " :) |
It might be seen as unorthodox 😂. How about just an 'A' for core::fmt::Arguments? |
It is not unorthodox if it is not seen ;D Having an But perhaps a new entry point would be best, that way we do not "pollute" Anyway, it is not a big deal -- the important bit is avoiding the stack! |
If we don't want the C code to use it, do we need to respect the precision and field width specified in printf specifier? If not, then the C side could be even simpler. |
Yeah, I do not think we need. Perhaps we could have a check nevertheless that the value is the expected default one, or something like that. |
Checking printf specs for default value requires as much change as supporting them. If we can just ignore the values, then we only need to declare and call the function prototypes in |
| grep -E ' (T|R|D) ' | cut -d ' ' -f 3 | grep -E '^(__rust_|_R)' \ | ||
| grep -E ' (T|R|D) ' | cut -d ' ' -f 3 \ |
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.
Why do we need to remove the filtering? Which symbols are needed now?
(Also, please put the reason in the commit message.)
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.
This is to expose the no_mangle
-ed symbol so functions can be called from C-side. I actually don't understand why there is the filtering in the first place, since nm
is only showing defined symbols anyway.
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.
The ones that would appear would be:
__rdl_oom
__rg_oom
__rg_alloc
__rg_alloc_zeroed
__rg_dealloc
__rg_realloc
rust_oom
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.
Sorry I don't quite get it, why shouldn't they appear?
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.
I was simply stating the ones for information. :)
I do not remember if there were other symbols being included when I wrote it originally. Perhaps I was trying to ensure we did not expose anything else, or trying to use the smaller set I could.
Should those 7 be exposed, i.e. do we expect rustc
to emit calls to those? (even from e.g. generics?)
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.
I mean emitting calls to those from leaf modules or external third-party modules; and by "from generics" I mean whether we could have a call in one of the generics in e.g. kernel
and then a leaf module instantiating that generic, generating the call etc.
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.
If it is not something that can be easily answered, or not guaranteed, or something like that, we can remove the filtering, it is not a big deal.
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.
I checked the disassembly, and it seems they are never called directly, but always through __rust_alloc
, __rust_alloc_error_handler
and friends. Anyway even if we want some filter it should be a denylist rather than by symbol prefixes?
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.
Yeah, the prefixes approach was intended to pick the "Rust-y" symbols. If we go for a list, perhaps the opposite: only allowing the ones we really need (that way we cover future ones that may appear etc.). We can put the adding the list on an issue.
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.
I'll just leave it as is then. We can open an issue to investigate what's best approach for symbol exports.
core::fmt::Argument
in vsprintfcore::fmt::Argument
in vsprintf
This comment has been minimized.
This comment has been minimized.
Changed |
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.
Usual nits.
Looks much simpler now, which is always good, and it is always a pleasure to remove code ;) Please add some explanation in the commit message. I know I am annoying :) but I insist on this because it is how every change will be required to be in the kernel, so I prefer that everybody gets accustomed before we get there :) In our case it is even more important, because we are using GitHub and our discussions are not officially archived in lore etc. as other patches/discussions are. |
This comment has been minimized.
This comment has been minimized.
This patch adds a format specifier `%pA` to `vsprintf` which formats a pointer as `core::fmt::Arguments`. Doing so allows us to directly format to the internal buffer of printf, so we don't have to use a temporary buffer on the stack to pre-assemble the message on the Rust side. This specifier is intended only to be used from Rust and not for C, so `checkpatch.pl` is intentionally unchanged to catch any misuse. Signed-off-by: Gary Guo <[email protected]>
Review of
|
Changed |
Any blocker? |
In which cases it is needed? |
LGTM |
It's part of Rust 2018 edition idioms. https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#elided-lifetimes-in-paths. It's recommended to spell out lifetime arguments. I'll enable |
Ah, thanks for the pointer! I did not know about that. |
This PR adds to format
%pfr
format tovsprintf
which formats a pointer as acore::fmt::Arguments
. Doing so allows us to directly format to the internal buffer of printk, so we don't have to assemble the message on a temporary buffer on the stack.This does however require changes on the C-side, so I made this PR a RFC.