Skip to content

Commit

Permalink
Support naked functions
Browse files Browse the repository at this point in the history
Fixes #1203
  • Loading branch information
bjorn3 committed May 12, 2024
1 parent 0627c63 commit cba05a7
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 48 deletions.
2 changes: 1 addition & 1 deletion build_system/build_sysroot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ fn build_clif_sysroot_for_triple(
if channel == "release" {
build_cmd.arg("--release");
}
build_cmd.arg("--features").arg("compiler-builtins-no-asm backtrace panic-unwind");
build_cmd.arg("--features").arg("backtrace panic-unwind");
build_cmd.env("CARGO_PROFILE_RELEASE_DEBUG", "true");
build_cmd.env("__CARGO_DEFAULT_LIB_METADATA", "cg_clif");
if compiler.triple.contains("apple") {
Expand Down
10 changes: 10 additions & 0 deletions example/mini_core_hello_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
never_type,
linkage,
extern_types,
naked_functions,
thread_local,
repr_simd,
raw_ref_op
Expand Down Expand Up @@ -340,6 +341,7 @@ fn main() {
))]
unsafe {
global_asm_test();
naked_test();
}

// Both statics have a reference that points to the same anonymous allocation.
Expand Down Expand Up @@ -395,6 +397,14 @@ global_asm! {
"
}

#[cfg(all(not(jit), not(no_unstable_features), target_arch = "x86_64"))]
#[naked]
extern "C" fn naked_test() {
unsafe {
asm!("ret", options(noreturn));
}
}

#[repr(C)]
enum c_void {
_1,
Expand Down
37 changes: 35 additions & 2 deletions src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
use cranelift_module::ModuleError;
use rustc_ast::InlineAsmOptions;
use rustc_index::IndexVec;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::layout::FnAbiOf;
use rustc_middle::ty::print::with_no_trimmed_paths;
Expand All @@ -14,6 +15,7 @@ use rustc_monomorphize::is_call_from_compiler_builtins_to_upstream_monomorphizat

use crate::constant::ConstantCx;
use crate::debuginfo::{FunctionDebugContext, TypeDebugContext};
use crate::inline_asm::codegen_naked_asm;
use crate::prelude::*;
use crate::pretty_clif::CommentWriter;

Expand All @@ -32,7 +34,7 @@ pub(crate) fn codegen_fn<'tcx>(
cached_func: Function,
module: &mut dyn Module,
instance: Instance<'tcx>,
) -> CodegenedFunction {
) -> Option<CodegenedFunction> {
debug_assert!(!instance.args.has_infer());

let symbol_name = tcx.symbol_name(instance).name.to_string();
Expand All @@ -48,6 +50,37 @@ pub(crate) fn codegen_fn<'tcx>(
String::from_utf8_lossy(&buf).into_owned()
});

if tcx.codegen_fn_attrs(instance.def_id()).flags.contains(CodegenFnAttrFlags::NAKED) {
assert_eq!(mir.basic_blocks.len(), 1);
assert!(mir.basic_blocks[START_BLOCK].statements.is_empty());

match &mir.basic_blocks[START_BLOCK].terminator().kind {
TerminatorKind::InlineAsm {
template,
operands,
options,
line_spans: _,
targets: _,
unwind: _,
} => {
codegen_naked_asm(
tcx,
cx,
module,
instance,
mir.basic_blocks[START_BLOCK].terminator().source_info.span,
&symbol_name,
template,
operands,
*options,
);
}
_ => unreachable!(),
}

return None;
}

// Declare function
let sig = get_function_sig(tcx, module.target_config().default_call_conv, instance);
let func_id = module.declare_function(&symbol_name, Linkage::Local, &sig).unwrap();
Expand Down Expand Up @@ -128,7 +161,7 @@ pub(crate) fn codegen_fn<'tcx>(
// Verify function
verify_func(tcx, &clif_comments, &func);

CodegenedFunction { symbol_name, func_id, func, clif_comments, func_debug_cx }
Some(CodegenedFunction { symbol_name, func_id, func, clif_comments, func_debug_cx })
}

pub(crate) fn compile_fn(
Expand Down
7 changes: 4 additions & 3 deletions src/driver/aot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,15 +482,16 @@ fn module_codegen(
for (mono_item, _) in mono_items {
match mono_item {
MonoItem::Fn(inst) => {
let codegened_function = crate::base::codegen_fn(
if let Some(codegened_function) = crate::base::codegen_fn(
tcx,
&mut cx,
&mut type_dbg,
Function::new(),
&mut module,
inst,
);
codegened_functions.push(codegened_function);
) {
codegened_functions.push(codegened_function);
}
}
MonoItem::Static(def_id) => {
let data_id = crate::constant::codegen_static(tcx, &mut module, def_id);
Expand Down
8 changes: 4 additions & 4 deletions src/driver/jit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,16 +232,16 @@ pub(crate) fn codegen_and_compile_fn<'tcx>(
crate::PrintOnPanic(|| format!("{:?} {}", instance, tcx.symbol_name(instance).name));

let cached_func = std::mem::replace(&mut cached_context.func, Function::new());
let codegened_func = crate::base::codegen_fn(
if let Some(codegened_func) = crate::base::codegen_fn(
tcx,
cx,
&mut TypeDebugContext::default(),
cached_func,
module,
instance,
);

crate::base::compile_fn(cx, cached_context, module, codegened_func);
) {
crate::base::compile_fn(cx, cached_context, module, codegened_func);
}
});
}

Expand Down
16 changes: 15 additions & 1 deletion src/driver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
//! [`codegen_static`]: crate::constant::codegen_static
use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir::mono::{MonoItem, MonoItemData};

use crate::prelude::*;
Expand Down Expand Up @@ -33,7 +34,20 @@ fn predefine_mono_items<'tcx>(
data.visibility,
is_compiler_builtins,
);
module.declare_function(name, linkage, &sig).unwrap();
let is_naked = tcx
.codegen_fn_attrs(instance.def_id())
.flags
.contains(CodegenFnAttrFlags::NAKED);
module
.declare_function(
name,
// Naked functions are defined in a separate object
// file from the codegen unit rustc expects them to
// be defined in.
if is_naked { Linkage::Import } else { linkage },
&sig,
)
.unwrap();
}
MonoItem::Static(_) | MonoItem::GlobalAsm(_) => {}
}
Expand Down
Loading

0 comments on commit cba05a7

Please sign in to comment.