Path: blob/main/cranelift/object/tests/basic.rs
1692 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]75fn switch_error() {76use cranelift_codegen::settings;7778let sig = Signature {79params: vec![AbiParam::new(types::I32)],80returns: vec![AbiParam::new(types::I32)],81call_conv: CallConv::SystemV,82};8384let mut func = Function::with_name_signature(UserFuncName::default(), sig);85let mut func_ctx = FunctionBuilderContext::new();86{87let mut bcx: FunctionBuilder = FunctionBuilder::new(&mut func, &mut func_ctx);88let start = bcx.create_block();89let bb0 = bcx.create_block();90let bb1 = bcx.create_block();91let bb2 = bcx.create_block();92let bb3 = bcx.create_block();93println!("{start} {bb0} {bb1} {bb2} {bb3}");9495bcx.declare_var(types::I32);96bcx.declare_var(types::I32);97let in_val = bcx.append_block_param(start, types::I32);98bcx.switch_to_block(start);99bcx.def_var(Variable::new(0), in_val);100bcx.ins().jump(bb0, &[]);101102bcx.switch_to_block(bb0);103let discr = bcx.use_var(Variable::new(0));104let mut switch = cranelift_frontend::Switch::new();105for &(index, bb) in &[106(9, bb1),107(13, bb1),108(10, bb1),109(92, bb1),110(39, bb1),111(34, bb1),112] {113switch.set_entry(index, bb);114}115switch.emit(&mut bcx, discr, bb2);116117bcx.switch_to_block(bb1);118let v = bcx.use_var(Variable::new(0));119bcx.def_var(Variable::new(1), v);120bcx.ins().jump(bb3, &[]);121122bcx.switch_to_block(bb2);123let v = bcx.use_var(Variable::new(0));124bcx.def_var(Variable::new(1), v);125bcx.ins().jump(bb3, &[]);126127bcx.switch_to_block(bb3);128let r = bcx.use_var(Variable::new(1));129bcx.ins().return_(&[r]);130131bcx.seal_all_blocks();132bcx.finalize();133}134135let flags = settings::Flags::new(settings::builder());136match cranelift_codegen::verify_function(&func, &flags) {137Ok(_) => {}138Err(err) => {139let pretty_error =140cranelift_codegen::print_errors::pretty_verifier_error(&func, None, err);141panic!("pretty_error:\n{pretty_error}");142}143}144}145146#[test]147fn libcall_function() {148let flag_builder = settings::builder();149let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap();150let isa = isa_builder151.finish(settings::Flags::new(flag_builder))152.unwrap();153let mut module =154ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap());155156let sig = Signature {157params: vec![],158returns: vec![],159call_conv: CallConv::SystemV,160};161162let func_id = module163.declare_function("function", Linkage::Local, &sig)164.unwrap();165166let mut ctx = Context::new();167ctx.func = Function::with_name_signature(UserFuncName::user(0, func_id.as_u32()), sig);168let mut func_ctx = FunctionBuilderContext::new();169{170let mut bcx: FunctionBuilder = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);171let block = bcx.create_block();172bcx.switch_to_block(block);173174let int = module.target_config().pointer_type();175let zero = bcx.ins().iconst(I16, 0);176let size = bcx.ins().iconst(int, 10);177178let mut signature = module.make_signature();179signature.params.push(AbiParam::new(int));180signature.returns.push(AbiParam::new(int));181let callee = module182.declare_function("malloc", Linkage::Import, &signature)183.expect("declare malloc function");184let local_callee = module.declare_func_in_func(callee, &mut bcx.func);185let argument_exprs = vec![size];186let call = bcx.ins().call(local_callee, &argument_exprs);187let buffer = bcx.inst_results(call)[0];188189bcx.call_memset(module.target_config(), buffer, zero, size);190191bcx.ins().return_(&[]);192}193194module.define_function(func_id, &mut ctx).unwrap();195196module.finish();197}198199#[test]200#[should_panic(expected = "has a null byte, which is disallowed")]201fn reject_nul_byte_symbol_for_func() {202let flag_builder = settings::builder();203let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap();204let isa = isa_builder205.finish(settings::Flags::new(flag_builder))206.unwrap();207let mut module =208ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap());209210let sig = Signature {211params: vec![],212returns: vec![],213call_conv: CallConv::SystemV,214};215216let _ = module217.declare_function("function\u{0}with\u{0}nul\u{0}bytes", Linkage::Local, &sig)218.unwrap();219}220221#[test]222#[should_panic(expected = "has a null byte, which is disallowed")]223fn reject_nul_byte_symbol_for_data() {224let flag_builder = settings::builder();225let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap();226let isa = isa_builder227.finish(settings::Flags::new(flag_builder))228.unwrap();229let mut module =230ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap());231232let _ = module233.declare_data(234"data\u{0}with\u{0}nul\u{0}bytes",235Linkage::Local,236/* writable = */ true,237/* tls = */ false,238)239.unwrap();240}241242243