Skip to content

Functions referenced by global_asm merged into other functions by LLVM #96797

Closed
@nbdd0121

Description

@nbdd0121
#![feature(asm_sym)]

use std::arch::global_asm;

#[no_mangle]
fn my_func() {}

global_asm!("call_foobar: jmp {}", sym foobar);

fn foobar() {}

fn main() {
    extern "Rust" {
        fn call_foobar();
    }
    unsafe { call_foobar() };
}

This code will fail to link because foobar is merged into my_func.

Since global asms in LLVM can't reference symbols natively, we currently will add the mangled name to the string and pass it to LLVM. To prevent the file being optimized away, we add it to llvm.compiler.used.

A few issues exist:

  • rustc_monomorphize does not handle these functions specially, and therefore foobar above is considered as internal function and have internal attribute attached.
  • LLVM believes that it is allowed to merge internal functions into an exported function despite present in llvm.compiler.used. I think LLVM should be allowed to this because we emit the internal linkage, and from my understanding renaming a local symbol should probably be allowed. @tmiasko argues otherwise and says that llvm.compiler.used shouldn't touch the symbol.
  • The symbols are added llvm.compiler.used, but it wouldn't show up as used in the exported symbol list, so it can still be stripped while doing LTO.

We should do the following:

  • Ensure that these functions are not emitted with internal linkage
  • Ensrue that the functions used will be marked as used in exported_symbols/linked_symbols and thus reach the linker/LTO.
  • Ask LLVM to clarify the behaviour of combining llvm.compiler.used + internal .

cc @Amanieu @tmiasko
@rustbot label: +A-inline-assembly +F-asm

This will block #93333

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-inline-assemblyArea: Inline assembly (`asm!(…)`)F-asm`#![feature(asm)]` (not `llvm_asm`)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions