-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
RFC: patchable-function-entry #3543
RFC: patchable-function-entry #3543
Conversation
Support adding a user-specified number of nops before functions and before the prelude.
3255007
to
83aa13b
Compare
How much do you want to allow users to depend on this? I.e. is this a guarantee, or just a hint? Asking because there might potentially be backends that can't/don't support this and it would be useful to document if they should ignore this, or error. |
I think that probably the behavior should be to error if the backend doesn't support it and a non-zero padding has been specified. This would allow users to set Thanks for the suggestion; I've added it to the design. |
18fa6f0
to
0b0e428
Compare
Seems useful! One thing I'd mention is that seeing |
First of all, 👍 for adding this functionality. Having both the command-line option and the attribute take two numeric parameters, but with different meanings, seems error-prone. I do appreciate that projects might not want to have to compute different numbers in their build systems for rustc, though. Given that, I do think we should use some syntax that requires the codegen options to specify which parameters they're defining, as suggested in your alternatives section (but without allowing any bare numeric versions), allowing As for the attribute, bikeshedding slightly, I had the same concern as @zachs18 that the attribute with no parameters feels like it should mean patchable rather than unpatchable. I also think it seems awkward to duplicate the word "entry" in
|
@rfcbot merge This seems like a reasonable use case to support, so I think we should do it. I agree with @joshtriplett that the differing meanings between the CLI flag and the attribute will create confusion. We should do something to mitigate that. @rfcbot concern difference between flag and attribute count meanings is confusing |
Team member @tmandry has proposed to merge this. The next step is review by the rest of the tagged team members:
Concerns:
Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! cc @rust-lang/lang-advisors: FCP proposed for lang, please feel free to register concerns. |
// Code goes here | ||
``` | ||
|
||
Nop padding may not be supported on all architectures. As of the time of writing, support includes: |
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.
Until this point I was under an impression that this is a pretty trivial feature and that there shouldn’t be any major reasons why it wouldn't be supported for an architecture. Is this entirely an engineering resource issue on the backend side?
The RFC should specify how we’ll handle unsupported platforms (do we need to make it stable on a per-architecture basis? Similar to #[target_feature(enable=...)]
flag?) I guess we also need to account for backends like cranelift which might not support the patchable entry feature at all...
EDIT: ah, I see you mentioned errors below.
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.
My understanding is that it's an engineering issue for most architectures/backends. For example, I don't think wasm can meaningfully do this.
The listed supported architectures are based on what LLVM currently supports.
- `-C patchable-function-entry=nop_count=m,offset=n` (`nop_count=m`, `offset=n`, modern format, offset optional) | ||
- `-C patchable-function-entry=prefix=m,entry=n` (`prefix=m`, `entry=n`, modern format, either optional) | ||
|
||
This would have the benefit of making it more clear what's being specified and allowing users to employ the simpler format on the command line if not integrating with an existing build. |
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.
Another benefit is that it would allow a potential design choice of -Cpatchable-function-entry=nop_count=n -Cpatchable-function-entry=offset=m
or e.g. overriding only a part of the specification for individual rustc invocations: env RUSTFLAGS=-Cpatchable-function-entry=nop_count=n,offset=m rustc $RUSTFLAGS ... -Cpatchable-function-entry=nop_count=x
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 counterpoint here is that -Cpatchable-function-entry=offset=m
for m
nonzero is illegal without a corresponding nop_count
, because the default nop count is 0, so the default offset needs to be smaller.
If we support both styles, then specifying just one could be nice, since prefix
and entry
can be meaningfully specified separately.
|
||
To set this for all functions in a crate, use `-C patchable-function-entry=nop_count,offset` where `nop_count = prefix + entry`, and `offset = prefix`. Usually, you'll want to copy this value from a corresponding `-fpatchable-function-entry=` being passed to the C compiler in your project. | ||
|
||
To set this for a specific function, use `#[patchable_function_entry(prefix(m), entry(n))]` to pad with m nops before the symbol and n after the symbol, but before the prelude. This will override the flag value. |
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 bikeshedding, but is there a reason to have these as a MetaList instead of a NameValue? To me, prefix = n seems more intuitive than a function call-type syntax.
@rustbot labels -I-lang-nominated We discussed this in the T-lang triage meeting on 2023-12-20 and that resulted in the proposed FCP merge and also the concern that divergent meanings between the CLI flag and the attribute may create confusion. Please renominate if there are questions or progress on addressing that concern that should be discussed by T-lang. |
How does this interact with inlining? Isn't this entirely nonsensical if a function gets inlined? I'd a user expected to use |
This should begin to address concerns about confusions between different flag vs attribute. Specifically: * Require command line flag to specify parameter names * Switch attribute name to `patchable` * Use metalist format for `patchable`, and require at least one parameter * Add `unpatchable` alias
Since I do agree that I'm not sure how I feel about One way of framing this is: "What do we call this feature?" "Patchable" seems pretty vague and high-level. It doesn't provide many "memory hooks" as to what it actually does. "Patchable function entry" is much better in that regard. "Patchable entry" is almost as good, given the context of being applied to a function. On that note, I think the name |
Before I update the RFC again, let me put some responses inline to check things.
The logic here at the moment is that it is referred to as the
I'm fine naming this either way. I don't think it will be written commonly, so I don't have strong feelings about an ergonomic name.
I called it
I think that even for users for whom this feature is extremely important, they will write each of these keywords somewhere between 1 and 3 times. |
I think you're doing a good job of weighing the viewpoint of the user who writes the annotation (or flag), @maurer. I'm considering things more from the perspective of a reader of the code. The code will be read many more times than it is written. Anyway, to that end, I'll make a concrete proposal from the current state of the RFC:
The reason being that these are more self-explanatory names. We lose the property that |
@rfcbot reviewed I am generally aligned with @tmandry here, and I concur with @wesleywiser that we should try not to make monomorphization behavior hard-coded. I'm signalling as reviewed because I trust the thread to reach reasonable conclusions. My general preferences are:
I'm of mixed minds about |
Re-reading, I see @joshtriplett wrote...
That makes sense to me, it'd be useful to know how often "unpatchable" functions arise in practice in existing codebases. I had imagined this being a fairly rare thing. |
To give you an idea of frequency, the way to do this in Linux in C is spelled
We could definitely use a more specific name than That said, I don't think it would be a show-stopper to only provide |
I too am generally a fan of fewer names, but there are realistic downsides to doing this with a macro today. You would have to use an attribute proc macro, which is annoying to implement and makes IDE integration worse, or wrap your function definitions inside of a |
Plan for next draft edits, in case someone thinks something's missing or wants to object:
|
Explicitly allow either an error or code generation at any patchability configuration in the crate graph. This allows all of: * Disallowing this (detect it and emit an error) * Doing what will happen by default today (functions will have the patchability of their codegen site) * Adding additional support down the line to use the patchability of the declaring crate. This is unlikely to be needed, but this leaves our options open for the future.
Some existing codegens (notably ELFv2+GCC+PPC) can only do some values of `prefix`/`entry`. Call out that it is possible for some values to cause errors, even if the target/backend combination supports patchability.
I've made the edits I said I'd make in the previous comment. Notably:
|
What is needed to move this forward? |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
The final comment period, with a disposition to merge, as per the review above, is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. This will be merged soon. |
Under "future possibilities", a sentence was missing the word "crate". Let's fix that.
RFC 3543 has been accepted. We've created the tracking issue. Let's add that to the RFC.
This RFC has been accepted by the teams and has now been merged. To track further progress on this, follow the tracking issue: Thanks to @maurer for authoring this RFC and for pushing it forward and to all those who reviewed it and provided useful feedback. |
This RFC proposes to add support for the
patchable-function-entry
family of flags and attributes fromclang
andgcc
in order to support instrumentation and patching as done in the Linux kernel.I have a candidate implementation and a MCP to cover just the compiler flag.
Rendered