Auto merge of #148339 - folkertdev:naked-macos-private-extern, r=Amanieu
naked functions: emit `.private_extern` on macos fixes https://github.com/rust-lang/rust/issues/148307 Emit `.private_extern` on macos when the naked function uses `Linkage::Internal`. Failing to do so can cause issues with LTO. The documentation on this directive is kind of sparse, but I believe this is at least not incorrect, and does fix the issue. r? @Amanieu cc @bjorn3
This commit is contained in:
commit
fecb335cba
4 changed files with 54 additions and 2 deletions
|
|
@ -181,7 +181,8 @@ fn prefix_and_suffix<'tcx>(
|
|||
}
|
||||
}
|
||||
Linkage::Internal => {
|
||||
// write nothing
|
||||
// LTO can fail when internal linkage is used.
|
||||
emit_fatal("naked functions may not have internal linkage")
|
||||
}
|
||||
Linkage::Common => emit_fatal("Functions may not have common linkage"),
|
||||
Linkage::AvailableExternally => {
|
||||
|
|
|
|||
|
|
@ -580,6 +580,16 @@ fn internalize_symbols<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
// When LTO inlines the caller of a naked function, it will attempt but fail to make the
|
||||
// naked function symbol visible. To ensure that LTO works correctly, do not default
|
||||
// naked functions to internal linkage and default visibility.
|
||||
if let MonoItem::Fn(instance) = item {
|
||||
let flags = cx.tcx.codegen_instance_attrs(instance.def).flags;
|
||||
if flags.contains(CodegenFnAttrFlags::NAKED) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If we got here, we did not find any uses from other CGUs, so
|
||||
// it's fine to make this monomorphization internal.
|
||||
data.linkage = Linkage::Internal;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
//@[aix] needs-llvm-components: powerpc
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(no_core, asm_experimental_arch, f128, linkage, fn_align)]
|
||||
#![feature(no_core, asm_experimental_arch)]
|
||||
#![no_core]
|
||||
|
||||
// tests that naked functions work for the `powerpc64-ibm-aix` target.
|
||||
|
|
|
|||
41
tests/assembly-llvm/naked-functions/hidden.rs
Normal file
41
tests/assembly-llvm/naked-functions/hidden.rs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
//@ revisions: macos-x86 macos-aarch64 linux-x86
|
||||
//@ add-minicore
|
||||
//@ assembly-output: emit-asm
|
||||
//
|
||||
//@[macos-aarch64] compile-flags: --target aarch64-apple-darwin
|
||||
//@[macos-aarch64] needs-llvm-components: aarch64
|
||||
//
|
||||
//@[macos-x86] compile-flags: --target x86_64-apple-darwin
|
||||
//@[macos-x86] needs-llvm-components: x86
|
||||
//
|
||||
//@[linux-x86] compile-flags: --target x86_64-unknown-linux-gnu
|
||||
//@[linux-x86] needs-llvm-components: x86
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(no_core, asm_experimental_arch)]
|
||||
#![no_core]
|
||||
|
||||
// Tests that naked functions that are not externally linked (e.g. via `no_mangle`)
|
||||
// are marked as `Visibility::Hidden` and emit `.private_extern` or `.hidden`.
|
||||
//
|
||||
// Without this directive, LTO may fail because the symbol is not visible.
|
||||
// See also https://github.com/rust-lang/rust/issues/148307.
|
||||
|
||||
extern crate minicore;
|
||||
use minicore::*;
|
||||
|
||||
// CHECK: .p2align 2
|
||||
// macos-x86,macos-aarch64: .private_extern
|
||||
// linux-x86: .globl
|
||||
// linux-x86: .hidden
|
||||
// CHECK: ret
|
||||
#[unsafe(naked)]
|
||||
extern "C" fn ret() {
|
||||
naked_asm!("ret")
|
||||
}
|
||||
|
||||
// CHECK-LABEL: entry
|
||||
#[no_mangle]
|
||||
pub fn entry() {
|
||||
ret()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue