-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
[AVR] Correctly set the pointer address space when constructing pointers to functions #73270
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
ea88e97
to
eba247c
Compare
eba247c
to
70b3f99
Compare
70b3f99
to
da62082
Compare
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
5a05b41
to
da4e901
Compare
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
326b9d8
to
c44ea2c
Compare
c44ea2c
to
9df636e
Compare
☔ The latest upstream changes (presumably #73504) made this pull request unmergeable. Please resolve the merge conflicts. |
9df636e
to
336322c
Compare
☔ The latest upstream changes (presumably #73528) made this pull request unmergeable. Please resolve the merge conflicts. |
Can we remove the hacks we made to the formatters with this PR? |
a3ff396
to
43d0a3a
Compare
I reverted 91bff8c from Rust master locally on top of this patch but then it breaks libcore
So it looks like we cannot remove the hacks we made to the formatters in 91bff8c with this PR. |
075eb4a
to
d348eca
Compare
d348eca
to
5a3f398
Compare
NOTE: I'm keeping tags of all of the iterations of this patch so we can compare and/or pull anything back in. https://github.com/dylanmckay/rust/releases/tag/avr-use-correct-addrspace.0 |
@dylanmckay is this still a draft? The implementation looks good to me… on a quick skim, anyway. |
@nagisa I haven't got around to writing it up properly, but yeah the implementation is no longer a draft - this is about as minimal as I could get the patch using the "stop using pointercast, always use bitcast" approach. I prefer this current approach to the boilerplate-heavy one located at the The only thing left before sending this PR back to review is... writing tests for it. I will flip this out of draft once that is done. |
5a3f398
to
97b6b9b
Compare
…ers to functions This patch extends the existing `type_i8p` method so that it requires an explicit address space to be specified. Before this patch, the `type_i8p` method implcitily assumed the default address space, which is not a safe transformation on all targets, namely AVR. The Rust compiler already has support for tracking the "instruction address space" on a per-target basis. This patch extends the code generation routines so that an address space must always be specified. In my estimation, around 15% of the callers of `type_i8p` produced invalid code on AVR due to the loss of address space prior to LLVM final code generation. This would lead to unavoidable assertion errors relating to invalid bitcasts. With this patch, the address space is always either 1) explicitly set to the instruction address space because the logic is dealing with functions which must be placed there, or 2) explicitly set to the default address space 0 because the logic can only operate on data space pointers and thus we keep the existing semantics of assuming the default, "data" address space.
…tated with the correct space Before this patch, a function pointer stored within an aggregate like a struct or an enum would always have the default address space `0`. This patch removes this assumption and instead, introspects the inner type being pointed at, storing the target address space in the PointeeInfo struct so that downstream users may query it.
97b6b9b
to
5581ce6
Compare
I've added a few tests. Whilst writing the tests, I noticed that I no longer needed to apply @eddyb's suggestion that changed all Back to review. |
@bors r+ |
📌 Commit 5581ce6 has been approved by |
…e, r=nagisa [AVR] Correctly set the pointer address space when constructing pointers to functions NOTE: Pull request iterations: * https://github.com/dylanmckay/rust/releases/tag/avr-use-correct-addrspace.0 * https://github.com/dylanmckay/rust/releases/tag/avr-use-correct-addrspace.1 * https://github.com/dylanmckay/rust/releases/tag/avr-use-correct-addrspace.2 This patch extends the existing `type_i8p` method so that it requires an explicit address space to be specified. Before this patch, the `type_i8p` method implcitily assumed the default address space, which is not a safe transformation on all targets, namely AVR. The Rust compiler already has support for tracking the "instruction address space" on a per-target basis. This patch extends the code generation routines so that an address space must always be specified. In my estimation, around 15% of the callers of `type_i8p` produced invalid code on AVR due to the loss of address space prior to LLVM final code generation. This would lead to unavoidable assertion errors relating to invalid bitcasts. With this patch, the address space is always either 1) explicitly preserved from the input type, or 2) explicitly set to the instruction address space because the logic is dealing with functions which must be placed there, or 3) explicitly set to the default address space 0 because the logic can only operate on data space pointers and thus we keep the existing semantics of assuming the default, "data" address space.
☀️ Test successful - checks-actions, checks-azure |
size: layout.size, | ||
align: layout.align.abi, |
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.
FWIW this makes very little sense. This sets the pointee size and alignment of function pointers to be the pointer size and alignment, i.e. on x86-64 this will be size 8 alignment 8, which is just completely wrong -- function pointers do not point to 8-aligned data.
Luckily these two fields are, from what I can tell, completely unused if safe
is None
(which does make me wonder why they are not inside the same Option
).
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.
Actually sounds like the entire approach of using PointeeInfo
to carry address space information is fundamentally broken; see this Zulip discussion.
unsafe { | ||
STORAGE_FOO(&1, &mut buf); | ||
} | ||
} |
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.
What happens when you store a function pointer in a type like Result<&'static u8, fn()>
? (Example due to @eddyb)
In LLVM this type gets translated as { i64, ptr }
, where the first field indicates Ok vs Err and the 2nd field contains the data (&u8
or fn()
, depending on the first field). So it is fundamentally impossible to have a dedicated function pointer address space here. Doesn't sound like the approach taken in this PR can possibly work here?
NOTE: Pull request iterations:
This patch extends the existing
type_i8p
method so that it requires anexplicit address space to be specified. Before this patch, the
type_i8p
method implcitily assumed the default address space, which isnot a safe transformation on all targets, namely AVR.
The Rust compiler already has support for tracking the "instruction
address space" on a per-target basis. This patch extends the code
generation routines so that an address space must always be specified.
In my estimation, around 15% of the callers of
type_i8p
producedinvalid code on AVR due to the loss of address space prior to LLVM final
code generation. This would lead to unavoidable assertion errors
relating to invalid bitcasts.
With this patch, the address space is always either 1) explicitly preserved
from the input type, or 2) explicitly set to the instruction address
space because the logic is dealing with functions which must be placed
there, or 3) explicitly set to the default address space 0 because the
logic can only operate on data space pointers and thus we keep the
existing semantics of assuming the default, "data" address space.