-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Use global_asm!
instead of external assembly files
#4306
Conversation
This commit moves the external assembly files of the `wasmtime-fiber` crate into `global_asm!` blocks defined in Rust. The motivation for doing this is not very strong at this time, but the points in favor of this are: * One less tool needed to cross-compile Wasmtime. A linker is still needed but perhaps one day that will improve as well. * A "modern" assembler, built-in to LLVM, is used instead of whatever appears on the system. The first point hasn't really cropped up that much and typically getting an assembler is just as hard as getting a linker nowadays. The second point though has us using `hint #xx` in aarch64 assembly instead of the actual instructions for assembler compatibility, and I believe that's no longer necessary because the LLVM assembler supports the modern instruction names. The translation of the x86/x86_64 assembly has been done to Intel syntax as well as opposed to the old AT&T syntax since that's Rust's default. Additionally s390x still remains in an external assembler file because `global_asm!` is still unstable in Rust on that platform.
// We need to tell whatever loads the following code (e.g. the dynamic linker) | ||
// that it is compatible with BTI, so that the corresponding executable memory | ||
// pages have the necessary attribute set (if supported by the environment). To | ||
// this end, we follow the ELF for the Arm® 64-bit Architecture standard, and | ||
// use a special metadata section. Further details are in section 6.2 of the | ||
// specification: | ||
// | ||
// https://github.com/ARM-software/abi-aa/blob/2022Q1/aaelf64/aaelf64.rst#program-property | ||
// | ||
// We also set the PAuth (PAC) property, even though it is optional, for the | ||
// sake of completeness. | ||
.pushsection .note.gnu.property, "a"; | ||
.p2align 3; | ||
.word 4; | ||
.word 16; | ||
.word 5; | ||
.asciz "GNU"; | ||
.word 0xc0000000; // GNU_PROPERTY_AARCH64_FEATURE_1_AND | ||
.word 4; | ||
.word 3; // GNU_PROPERTY_AARCH64_FEATURE_1_BTI | GNU_PROPERTY_AARCH64_FEATURE_1_PAC | ||
.word 0; | ||
.popsection | ||
#endif |
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.
@akirilov-arm I have temporarily dropped this block in the hopes that it's only required for external assembly files rather than global_asm!
blocks in Rust itself. I am not super familiar with global_asm!
though so I could be wrong here. Could you help by taking a peek at the artifacts of this PR (when they're available) and see if everything looks correct?
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.
For the sake of other people who might look at this PR - we are also discussing this issue in the Zulip chat.
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.
Ok while very roundabout I have confirmed that I don't believe it's necessary to include this section in the global_asm!
anywhere. The global_asm!
gets shoved directly into the final object file and the object files coming out of rustc otherwise have this section already configured with the -Zbranch-protection=bti
flag.
As I mentioned in Zulip there's a whole mess of other reason why the note won't show up but they're all unrelated to this stanza in this assembly (the other issues being that (a) your local rust precompiled standard library needs the note and (b) your local glibc toolchain with crt*.o
also needs the note, neither of which have it by default)
@@ -0,0 +1,82 @@ | |||
// A WORD OF CAUTION |
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.
Given that since PR #3799 Cranelift no longer supports the 32-bit Arm architecture, do we need to keep this file?
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.
It's true yeah, although knowing that I originally wrote this file and the x86.S file when I first made the wasmtime-fiber
crate. My thinking was that I had all the context of fibers booted into my head and the CFI directives and such in particular are really tricky so it was easy for me to bang out some other "maybe one day we'll support these" architectures here. These aren't actually tested on CI at all and there's no actual way to use them unless you use the wasmtime-fiber
crate directly (and why would you).
Personally I'd err on the side of leaving them here in the sense that I've tested them to make sure they work (even with this PR) and otherwise it's one less thing to add if anyone ever wants to add support for arm/x86. If anyone else spends even a crumb of thought on updating these files though they should definitely be deleted immediately as they're not worth that much.
// We need to tell whatever loads the following code (e.g. the dynamic linker) | ||
// that it is compatible with BTI, so that the corresponding executable memory | ||
// pages have the necessary attribute set (if supported by the environment). To | ||
// this end, we follow the ELF for the Arm® 64-bit Architecture standard, and | ||
// use a special metadata section. Further details are in section 6.2 of the | ||
// specification: | ||
// | ||
// https://github.com/ARM-software/abi-aa/blob/2022Q1/aaelf64/aaelf64.rst#program-property | ||
// | ||
// We also set the PAuth (PAC) property, even though it is optional, for the | ||
// sake of completeness. | ||
.pushsection .note.gnu.property, "a"; | ||
.p2align 3; | ||
.word 4; | ||
.word 16; | ||
.word 5; | ||
.asciz "GNU"; | ||
.word 0xc0000000; // GNU_PROPERTY_AARCH64_FEATURE_1_AND | ||
.word 4; | ||
.word 3; // GNU_PROPERTY_AARCH64_FEATURE_1_BTI | GNU_PROPERTY_AARCH64_FEATURE_1_PAC | ||
.word 0; | ||
.popsection | ||
#endif |
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.
For the sake of other people who might look at this PR - we are also discussing this issue in the Zulip chat.
I just went down a really long rabbit hole to justify the addition of 6a02949 here, namely adding
is a massive simplification of the
Here the Overall I don't know why there's this "global state" here or what this offset is. I suppose the word "global" in "global_asm" should have tipped me off. Anyway my hope here was that with the addition of This is probably a bug in LLVM though. The same assembly file above going through gcc yields:
Here it looks like gcc folded the FDE entry directly into the CIE because only one FDE references the CIE (I guess? unsure?). In any case the |
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 good to me, but note that out of the architecture-specific bits I have looked only at the AArch64 ones.
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.
Nice!
This unfortunately seems to have broken compilation on macOS/aarch64 with latest stable Rust (1.61.0):
I haven't dug into this at all but I can play with it more or test changes tomorrow if needed to help... |
(N.B.: all errors from The following patch seems to push it further:
unfortunately it then bottoms out at:
|
Oh oops this reminds me that I meant to poke you before I merged this and see if it compiles on your mac and completely forgot. I'll dig in tomorrow but feel free to revert in the meantime. |
No worries, as long as we dig in (I'm happy to help test) I don't think there's a need to revert immediately. Hopefully something simple to fix... |
OK, the following is sufficient to get everything to build and pass tests again (conditionalizing this just for macOS left as exercise for the reader):
basically I figured that the linker is probably putting the functions in different sections now (whereas the |
Ok I ended up cooking up #4341 which I'm hoping will work |
…e#4306) * Use `global_asm!` instead of external assembly files This commit moves the external assembly files of the `wasmtime-fiber` crate into `global_asm!` blocks defined in Rust. The motivation for doing this is not very strong at this time, but the points in favor of this are: * One less tool needed to cross-compile Wasmtime. A linker is still needed but perhaps one day that will improve as well. * A "modern" assembler, built-in to LLVM, is used instead of whatever appears on the system. The first point hasn't really cropped up that much and typically getting an assembler is just as hard as getting a linker nowadays. The second point though has us using `hint #xx` in aarch64 assembly instead of the actual instructions for assembler compatibility, and I believe that's no longer necessary because the LLVM assembler supports the modern instruction names. The translation of the x86/x86_64 assembly has been done to Intel syntax as well as opposed to the old AT&T syntax since that's Rust's default. Additionally s390x still remains in an external assembler file because `global_asm!` is still unstable in Rust on that platform. * Simplify alignment specification * Temporarily disable fail-fast * Add `.cfi_def_cfa_offset 0` to fix CI * Turn off fail-fast * Review comments
This commit moves the external assembly files of the
wasmtime-fiber
crate into
global_asm!
blocks defined in Rust. The motivation fordoing this is not very strong at this time, but the points in favor of
this are:
needed but perhaps one day that will improve as well.
appears on the system.
The first point hasn't really cropped up that much and typically getting
an assembler is just as hard as getting a linker nowadays. The second
point though has us using
hint #xx
in aarch64 assembly instead of theactual instructions for assembler compatibility, and I believe that's no
longer necessary because the LLVM assembler supports the modern
instruction names.
The translation of the x86/x86_64 assembly has been done to Intel
syntax as well as opposed to the old AT&T syntax since that's Rust's
default. Additionally s390x still remains in an external assembler file
because
global_asm!
is still unstable in Rust on that platform.