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