1 use cranelift_codegen::ir::*; 2 use cranelift_codegen::isa::CallConv; 3 use cranelift_codegen::settings; 4 use cranelift_codegen::{ir::types::I16, Context}; 5 use cranelift_entity::EntityRef; 6 use cranelift_frontend::*; 7 use cranelift_module::*; 8 use cranelift_object::*; 9 10 #[test] 11 fn error_on_incompatible_sig_in_declare_function() { 12 let flag_builder = settings::builder(); 13 let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap(); 14 let isa = isa_builder.finish(settings::Flags::new(flag_builder)); 15 let mut module = 16 ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap()); 17 let mut sig = Signature { 18 params: vec![AbiParam::new(types::I64)], 19 returns: vec![], 20 call_conv: CallConv::SystemV, 21 }; 22 module 23 .declare_function("abc", Linkage::Local, &sig) 24 .unwrap(); 25 sig.params[0] = AbiParam::new(types::I32); 26 module 27 .declare_function("abc", Linkage::Local, &sig) 28 .err() 29 .unwrap(); // Make sure this is an error 30 } 31 32 fn define_simple_function(module: &mut ObjectModule) -> FuncId { 33 let sig = Signature { 34 params: vec![], 35 returns: vec![], 36 call_conv: CallConv::SystemV, 37 }; 38 39 let func_id = module 40 .declare_function("abc", Linkage::Local, &sig) 41 .unwrap(); 42 43 let mut ctx = Context::new(); 44 ctx.func = Function::with_name_signature(ExternalName::user(0, func_id.as_u32()), sig); 45 let mut func_ctx = FunctionBuilderContext::new(); 46 { 47 let mut bcx: FunctionBuilder = FunctionBuilder::new(&mut ctx.func, &mut func_ctx); 48 let block = bcx.create_block(); 49 bcx.switch_to_block(block); 50 bcx.ins().return_(&[]); 51 } 52 53 module.define_function(func_id, &mut ctx).unwrap(); 54 55 func_id 56 } 57 58 #[test] 59 #[should_panic(expected = "Result::unwrap()` on an `Err` value: DuplicateDefinition(\"abc\")")] 60 fn panic_on_define_after_finalize() { 61 let flag_builder = settings::builder(); 62 let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap(); 63 let isa = isa_builder.finish(settings::Flags::new(flag_builder)); 64 let mut module = 65 ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap()); 66 67 define_simple_function(&mut module); 68 define_simple_function(&mut module); 69 } 70 71 #[test] 72 fn switch_error() { 73 use cranelift_codegen::settings; 74 75 let sig = Signature { 76 params: vec![AbiParam::new(types::I32)], 77 returns: vec![AbiParam::new(types::I32)], 78 call_conv: CallConv::SystemV, 79 }; 80 81 let mut func = Function::with_name_signature(ExternalName::user(0, 0), sig); 82 83 let mut func_ctx = FunctionBuilderContext::new(); 84 { 85 let mut bcx: FunctionBuilder = FunctionBuilder::new(&mut func, &mut func_ctx); 86 let start = bcx.create_block(); 87 let bb0 = bcx.create_block(); 88 let bb1 = bcx.create_block(); 89 let bb2 = bcx.create_block(); 90 let bb3 = bcx.create_block(); 91 println!("{} {} {} {} {}", start, bb0, bb1, bb2, bb3); 92 93 bcx.declare_var(Variable::new(0), types::I32); 94 bcx.declare_var(Variable::new(1), types::I32); 95 let in_val = bcx.append_block_param(start, types::I32); 96 bcx.switch_to_block(start); 97 bcx.def_var(Variable::new(0), in_val); 98 bcx.ins().jump(bb0, &[]); 99 100 bcx.switch_to_block(bb0); 101 let discr = bcx.use_var(Variable::new(0)); 102 let mut switch = cranelift_frontend::Switch::new(); 103 for &(index, bb) in &[ 104 (9, bb1), 105 (13, bb1), 106 (10, bb1), 107 (92, bb1), 108 (39, bb1), 109 (34, bb1), 110 ] { 111 switch.set_entry(index, bb); 112 } 113 switch.emit(&mut bcx, discr, bb2); 114 115 bcx.switch_to_block(bb1); 116 let v = bcx.use_var(Variable::new(0)); 117 bcx.def_var(Variable::new(1), v); 118 bcx.ins().jump(bb3, &[]); 119 120 bcx.switch_to_block(bb2); 121 let v = bcx.use_var(Variable::new(0)); 122 bcx.def_var(Variable::new(1), v); 123 bcx.ins().jump(bb3, &[]); 124 125 bcx.switch_to_block(bb3); 126 let r = bcx.use_var(Variable::new(1)); 127 bcx.ins().return_(&[r]); 128 129 bcx.seal_all_blocks(); 130 bcx.finalize(); 131 } 132 133 let flags = settings::Flags::new(settings::builder()); 134 match cranelift_codegen::verify_function(&func, &flags) { 135 Ok(_) => {} 136 Err(err) => { 137 let pretty_error = 138 cranelift_codegen::print_errors::pretty_verifier_error(&func, None, err); 139 panic!("pretty_error:\n{}", pretty_error); 140 } 141 } 142 } 143 144 #[test] 145 fn libcall_function() { 146 let flag_builder = settings::builder(); 147 let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap(); 148 let isa = isa_builder.finish(settings::Flags::new(flag_builder)); 149 let mut module = 150 ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap()); 151 152 let sig = Signature { 153 params: vec![], 154 returns: vec![], 155 call_conv: CallConv::SystemV, 156 }; 157 158 let func_id = module 159 .declare_function("function", Linkage::Local, &sig) 160 .unwrap(); 161 162 let mut ctx = Context::new(); 163 ctx.func = Function::with_name_signature(ExternalName::user(0, func_id.as_u32()), sig); 164 let mut func_ctx = FunctionBuilderContext::new(); 165 { 166 let mut bcx: FunctionBuilder = FunctionBuilder::new(&mut ctx.func, &mut func_ctx); 167 let block = bcx.create_block(); 168 bcx.switch_to_block(block); 169 170 let int = module.target_config().pointer_type(); 171 let zero = bcx.ins().iconst(I16, 0); 172 let size = bcx.ins().iconst(int, 10); 173 174 let mut signature = module.make_signature(); 175 signature.params.push(AbiParam::new(int)); 176 signature.returns.push(AbiParam::new(int)); 177 let callee = module 178 .declare_function("malloc", Linkage::Import, &signature) 179 .expect("declare malloc function"); 180 let local_callee = module.declare_func_in_func(callee, &mut bcx.func); 181 let argument_exprs = vec![size]; 182 let call = bcx.ins().call(local_callee, &argument_exprs); 183 let buffer = bcx.inst_results(call)[0]; 184 185 bcx.call_memset(module.target_config(), buffer, zero, size); 186 187 bcx.ins().return_(&[]); 188 } 189 190 module.define_function(func_id, &mut ctx).unwrap(); 191 192 module.finish(); 193 } 194 195 #[test] 196 #[should_panic( 197 expected = "Result::unwrap()` on an `Err` value: Backend(Symbol \"function\\u{0}with\\u{0}nul\\u{0}bytes\" has a null byte, which is disallowed" 198 )] 199 fn reject_nul_byte_symbol_for_func() { 200 let flag_builder = settings::builder(); 201 let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap(); 202 let isa = isa_builder.finish(settings::Flags::new(flag_builder)); 203 let mut module = 204 ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap()); 205 206 let sig = Signature { 207 params: vec![], 208 returns: vec![], 209 call_conv: CallConv::SystemV, 210 }; 211 212 let _ = module 213 .declare_function("function\u{0}with\u{0}nul\u{0}bytes", Linkage::Local, &sig) 214 .unwrap(); 215 } 216 217 #[test] 218 #[should_panic( 219 expected = "Result::unwrap()` on an `Err` value: Backend(Symbol \"data\\u{0}with\\u{0}nul\\u{0}bytes\" has a null byte, which is disallowed" 220 )] 221 fn reject_nul_byte_symbol_for_data() { 222 let flag_builder = settings::builder(); 223 let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap(); 224 let isa = isa_builder.finish(settings::Flags::new(flag_builder)); 225 let mut module = 226 ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap()); 227 228 let _ = module 229 .declare_data( 230 "data\u{0}with\u{0}nul\u{0}bytes", 231 Linkage::Local, 232 /* writable = */ true, 233 /* tls = */ false, 234 ) 235 .unwrap(); 236 } 237