Skip to content

Conversation

@bnjbvr
Copy link
Member

@bnjbvr bnjbvr commented Sep 1, 2021

Three commits that make the Mac M1 pass all the tests run in CI:

  • in the custom asm code for the fibers, on aarch64, the custom CFI directive that was indicating where FP (x29) lives was completely incorrect. The pushes in wasmtime_fiber_switch start with stp lr, fp, [sp, -16]!, so FP was at CFA - 0x8, not CFA - 0x60. Unclear why it did work in the first place, and why it stopped working at some point; likely that something in Apple's libunwind has changed in the meanwhile.
  • the OS page size is 16K, not 4K on Mac M1: a constant is used for the code section page's size, and defined per target, and reused in a few places in the code base. Thanks to @alexcrichton for indicating me the place to look at!
  • unfortunately we need to disable pointer authentication (until we implement it!) for function frames that don't have a prologue too. Preferred to split gen_prologue_frame_setup, so there's a new function gen_debug_frame_info that's defaulting to doing nothing, and implemented on aarch64 and disabling pointer auth. This function is called independently from the fact that the function requires a prologue/epilogue, so we can put the unwind instruction that will generate the CFI directive in there. cc @cfallin @akirilov-arm for this change

Fixes #3256.

@github-actions github-actions bot added cranelift Issues related to the Cranelift code generator cranelift:area:machinst Issues related to instruction selection and the new MachInst backend. cranelift:area:aarch64 Issues related to AArch64 backend. labels Sep 1, 2021
pub(crate) const CODE_SECTION_ALIGNMENT: u64 = 0x4000;

#[cfg(not(all(target_os = "macos", target_arch = "aarch64")))]
pub(crate) const CODE_SECTION_ALIGNMENT: u64 = 0x1000;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least on macOS you have to query the page size at runtime. This is for example necessary for Rosetta 2 to work as it uses AArch64 sized pages. There may be other cases where it isn't possible to know this at compile time. You can use region::page::size() to query it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL! @alexcrichton in this case, would it be just simpler to call region::page::size() (maybe cache it, if we expect this to be expensive) instead of having the raw constants scattered in the code?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a better fix for this would be to inspect self.isa.target() to accomodate cross-compiling use cases. If the section is over-aligned for some embeddings that's not an issue.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, fixed!

@bnjbvr
Copy link
Member Author

bnjbvr commented Sep 2, 2021

Seems that CI is running cargo check for 1.43 with a comment (from last year) stating it's necessary for Firefox, however Firefox has been updated to use 1.54 according to https://bugzilla.mozilla.org/show_bug.cgi?id=1723016. Can we remove this requirement now? (Of course can tweak the code to not use or patterns.)

Copy link
Member

@alexcrichton alexcrichton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasmtime bits look good to me, but someon else may wish to confirm the cranelift changes. Seems like updating rustc for that check is fine to me as well, yeah.

Firefox has updated its toolchain to something much more recent.
- run: cargo check --target wasm32-unknown-emscripten -p wasi-common
- run: cargo check --target armv7-unknown-linux-gnueabihf -p wasi-common

# Check that codegen and wasm crates typecheck on 1.43.0; this is required
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just bump it to a newer version instead of removing it completely?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was under the impression that Firefox is now following latest stable, so that cargo check step ought to be unnecessary. Plus, unclear whether Cranelift is still being updated from this particular repository or Mozilla's fork. I'll check in with the Mozilla folks, it'd be easy to add back later, if necessary.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yury from Mozilla confirmed on Matrix mozilla-central is using stable, so we should be good here!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't they updating like one week after a new rust version releases?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be, but Cranelift in Firefox seems to receive updates at a lesser frequency (which makes sense for their stability guarantees, and considering the Cranelift bug has been resolved as inactive). Last update was 3 months ago.

Copy link
Member

@cfallin cfallin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM on Cranelift/ABI bits as well -- thanks!

@cfallin cfallin merged commit 2389a4e into bytecodealliance:main Sep 2, 2021
@bnjbvr bnjbvr deleted the fix-m1 branch September 2, 2021 16:49
@akirilov-arm
Copy link
Contributor

@alexcrichton @bnjbvr I have just seen this:

The pushes in wasmtime_fiber_switch start with stp lr, fp, [sp, -16]!, so FP was at CFA - 0x8, not CFA - 0x60. Unclear why it did work in the first place, and why it stopped working at some point; likely that something in Apple's libunwind has changed in the meanwhile.

Is there any specific reason to push the registers in that order? The Procedure Call Standard actually specifies the reverse:

The lowest addressed double-word shall point to the previous frame record and the highest addressed double-word shall contain the value passed in LR on entry to the current function.

@bnjbvr
Copy link
Member Author

bnjbvr commented Sep 6, 2021

Is there any specific reason to push the registers in that order? The Procedure Call Standard actually specifies the reverse:

No, no particular reasons. One could easily get confused with the push order in stp...

@akirilov-arm
Copy link
Contributor

akirilov-arm commented Sep 7, 2021

Perhaps that is partially the cause of the issue with libunwind? I.e. maybe the unwinder has been changed to have stricter frame record layout expectations (in the presence of incorrect CFI information)?

@bnjbvr
Copy link
Member Author

bnjbvr commented Sep 7, 2021

Perhaps that is partially the cause of the issue with libunwind? I.e. maybe the unwinder has been changed to have stricter frame record layout expectations (in the presence of incorrect CFI information)?

No: the change in this PR was sufficient to make the test pass, and it wouldn't have been the case if the unwinder had very precise frame record layout expectations. That being said, I'm all in favor of using the most conforming push order :-)

@alexcrichton
Copy link
Member

Nah there is no reason to push the registers in that order, only that I'd never written arm64 assembly before when I wrote this. I think it would be best to follow arm64 conventions and standards though!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cranelift:area:aarch64 Issues related to AArch64 backend. cranelift:area:machinst Issues related to instruction selection and the new MachInst backend. cranelift Issues related to the Cranelift code generator

Projects

None yet

Development

Successfully merging this pull request may close these issues.

aarch64-darwin: crash when unwinding

5 participants