Skip to content
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

Inline assembly and CFA #66

Open
nagisa opened this issue Apr 3, 2022 · 0 comments
Open

Inline assembly and CFA #66

nagisa opened this issue Apr 3, 2022 · 0 comments

Comments

@nagisa
Copy link
Member

nagisa commented Apr 3, 2022

Using inline assembly to implement the functionality in psm would be beneficial for multiple reasons:

  • Most notably in that it would no longer require an external assembler to build the library, obviating the use of build.rs script; and
  • It would also resolve the issues of having to think about the different kinds of assemblers, allowing us to deal largely with just one sort of dialect; and
  • I can also see a potential micro-optimization wherein we could call the trampoline directly, rather than via indirect call (requires sym operands which are currently not stable yet;)
  • It allows linking multiple different versions of psm into the same binary (right now linking would fail due to symbol collisions;)

Alas, not all backends support inline assembly, possibly making it more difficult to bootstrap rustc.

I also found that it is difficult to properly support proper CFI/CFA information. For example on x86_64, the frame pointer omission is enabled by default, so e.g. for x86_64 the following code would be appropriate in some cases:

    ::core::arch::asm!(
        ".cfi_remember_state",
        "mov r12, rsp",
        ".cfi_def_cfa_register r12",
        "mov rsp, {new_sp}",
        "call {trampoline}",
        "mov rsp, r12",
        ".cfi_restore_state",
        ...
        out("r12") _
        clobber_abi("sysv64"),
    );

however this CFI becomes invalid as soon as frame-pointer is forced, either via the -Cforce-frame-pointers flag, target spec modification, or just because LLVM decided that a frame pointer is necessary for the function. When frame pointer is enabled we should not emit any .cfi directives for this sequence at all. This is also quite apparent when considering i686 targets, which enable the frame pointer by default, but disabling it is a common optimization people apply.

Alas, there doesn't seem to be any way to detect this as far as I can tell.


Global (module level) inline assembly may still be an option, though. It would still allow for some benefits (avoiding build.rs scripts, sym micro-optimization), while also giving sufficient flexibility necessary to maintain correct CFI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant