Path: blob/main/cranelift/object/tests/basic.rs
3063 views
use cranelift_codegen::ir::*;1use cranelift_codegen::isa::CallConv;2use cranelift_codegen::settings;3use cranelift_codegen::{Context, ir::types::I16};4use cranelift_entity::EntityRef;5use cranelift_frontend::*;6use cranelift_module::*;7use cranelift_object::*;89#[test]10fn error_on_incompatible_sig_in_declare_function() {11let flag_builder = settings::builder();12let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap();13let isa = isa_builder14.finish(settings::Flags::new(flag_builder))15.unwrap();16let mut module =17ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap());18let mut sig = Signature {19params: vec![AbiParam::new(types::I64)],20returns: vec![],21call_conv: CallConv::SystemV,22};23module24.declare_function("abc", Linkage::Local, &sig)25.unwrap();26sig.params[0] = AbiParam::new(types::I32);27module28.declare_function("abc", Linkage::Local, &sig)29.err()30.unwrap(); // Make sure this is an error31}3233fn define_simple_function(module: &mut ObjectModule) -> FuncId {34let sig = Signature {35params: vec![],36returns: vec![],37call_conv: CallConv::SystemV,38};3940let func_id = module41.declare_function("abc", Linkage::Local, &sig)42.unwrap();4344let mut ctx = Context::new();45ctx.func = Function::with_name_signature(UserFuncName::user(0, func_id.as_u32()), sig);46let mut func_ctx = FunctionBuilderContext::new();47{48let mut bcx: FunctionBuilder = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);49let block = bcx.create_block();50bcx.switch_to_block(block);51bcx.ins().return_(&[]);52}5354module.define_function(func_id, &mut ctx).unwrap();5556func_id57}5859#[test]60#[should_panic(expected = "Result::unwrap()` on an `Err` value: DuplicateDefinition(\"abc\")")]61fn panic_on_define_after_finalize() {62let flag_builder = settings::builder();63let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap();64let isa = isa_builder65.finish(settings::Flags::new(flag_builder))66.unwrap();67let mut module =68ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap());6970define_simple_function(&mut module);71define_simple_function(&mut module);72}7374#[test]75#[cfg_attr(not(debug_assertions), ignore = "checks a debug assertion")]76#[should_panic(expected = "function \"abc\" with linkage Local must be defined but is not")]77fn panic_on_declare_without_define() {78let flag_builder = settings::builder();79let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap();80let isa = isa_builder81.finish(settings::Flags::new(flag_builder))82.unwrap();83let mut module =84ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap());8586module87.declare_function("abc", Linkage::Local, &Signature::new(CallConv::SystemV))88.unwrap();8990module.finish();91}9293#[test]94fn switch_error() {95use cranelift_codegen::settings;9697let sig = Signature {98params: vec![AbiParam::new(types::I32)],99returns: vec![AbiParam::new(types::I32)],100call_conv: CallConv::SystemV,101};102103let mut func = Function::with_name_signature(UserFuncName::default(), sig);104let mut func_ctx = FunctionBuilderContext::new();105{106let mut bcx: FunctionBuilder = FunctionBuilder::new(&mut func, &mut func_ctx);107let start = bcx.create_block();108let bb0 = bcx.create_block();109let bb1 = bcx.create_block();110let bb2 = bcx.create_block();111let bb3 = bcx.create_block();112println!("{start} {bb0} {bb1} {bb2} {bb3}");113114bcx.declare_var(types::I32);115bcx.declare_var(types::I32);116let in_val = bcx.append_block_param(start, types::I32);117bcx.switch_to_block(start);118bcx.def_var(Variable::new(0), in_val);119bcx.ins().jump(bb0, &[]);120121bcx.switch_to_block(bb0);122let discr = bcx.use_var(Variable::new(0));123let mut switch = cranelift_frontend::Switch::new();124for &(index, bb) in &[125(9, bb1),126(13, bb1),127(10, bb1),128(92, bb1),129(39, bb1),130(34, bb1),131] {132switch.set_entry(index, bb);133}134switch.emit(&mut bcx, discr, bb2);135136bcx.switch_to_block(bb1);137let v = bcx.use_var(Variable::new(0));138bcx.def_var(Variable::new(1), v);139bcx.ins().jump(bb3, &[]);140141bcx.switch_to_block(bb2);142let v = bcx.use_var(Variable::new(0));143bcx.def_var(Variable::new(1), v);144bcx.ins().jump(bb3, &[]);145146bcx.switch_to_block(bb3);147let r = bcx.use_var(Variable::new(1));148bcx.ins().return_(&[r]);149150bcx.seal_all_blocks();151bcx.finalize();152}153154let flags = settings::Flags::new(settings::builder());155match cranelift_codegen::verify_function(&func, &flags) {156Ok(_) => {}157Err(err) => {158let pretty_error =159cranelift_codegen::print_errors::pretty_verifier_error(&func, None, err);160panic!("pretty_error:\n{pretty_error}");161}162}163}164165#[test]166fn libcall_function() {167let flag_builder = settings::builder();168let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap();169let isa = isa_builder170.finish(settings::Flags::new(flag_builder))171.unwrap();172let mut module =173ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap());174175let sig = Signature {176params: vec![],177returns: vec![],178call_conv: CallConv::SystemV,179};180181let func_id = module182.declare_function("function", Linkage::Local, &sig)183.unwrap();184185let mut ctx = Context::new();186ctx.func = Function::with_name_signature(UserFuncName::user(0, func_id.as_u32()), sig);187let mut func_ctx = FunctionBuilderContext::new();188{189let mut bcx: FunctionBuilder = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);190let block = bcx.create_block();191bcx.switch_to_block(block);192193let int = module.target_config().pointer_type();194let zero = bcx.ins().iconst(I16, 0);195let size = bcx.ins().iconst(int, 10);196197let mut signature = module.make_signature();198signature.params.push(AbiParam::new(int));199signature.returns.push(AbiParam::new(int));200let callee = module201.declare_function("malloc", Linkage::Import, &signature)202.expect("declare malloc function");203let local_callee = module.declare_func_in_func(callee, &mut bcx.func);204let argument_exprs = vec![size];205let call = bcx.ins().call(local_callee, &argument_exprs);206let buffer = bcx.inst_results(call)[0];207208bcx.call_memset(module.target_config(), buffer, zero, size);209210bcx.ins().return_(&[]);211}212213module.define_function(func_id, &mut ctx).unwrap();214215module.finish();216}217218#[test]219#[should_panic(expected = "has a null byte, which is disallowed")]220fn reject_nul_byte_symbol_for_func() {221let flag_builder = settings::builder();222let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap();223let isa = isa_builder224.finish(settings::Flags::new(flag_builder))225.unwrap();226let mut module =227ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap());228229let sig = Signature {230params: vec![],231returns: vec![],232call_conv: CallConv::SystemV,233};234235let _ = module236.declare_function("function\u{0}with\u{0}nul\u{0}bytes", Linkage::Local, &sig)237.unwrap();238}239240#[test]241#[should_panic(expected = "has a null byte, which is disallowed")]242fn reject_nul_byte_symbol_for_data() {243let flag_builder = settings::builder();244let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap();245let isa = isa_builder246.finish(settings::Flags::new(flag_builder))247.unwrap();248let mut module =249ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap());250251let _ = module252.declare_data(253"data\u{0}with\u{0}nul\u{0}bytes",254Linkage::Local,255/* writable = */ true,256/* tls = */ false,257)258.unwrap();259}260261262