1 use cranelift_codegen::ir::*; 2 use cranelift_codegen::isa::CallConv; 3 use cranelift_codegen::settings; 4 use cranelift_codegen::{Context, ir::types::I16}; 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(UserFuncName::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 #[cfg_attr(not(debug_assertions), ignore = "checks a debug assertion")] 77 #[should_panic(expected = "function \"abc\" with linkage Local must be defined but is not")] 78 fn panic_on_declare_without_define() { 79 let flag_builder = settings::builder(); 80 let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap(); 81 let isa = isa_builder 82 .finish(settings::Flags::new(flag_builder)) 83 .unwrap(); 84 let mut module = 85 ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap()); 86 87 module 88 .declare_function("abc", Linkage::Local, &Signature::new(CallConv::SystemV)) 89 .unwrap(); 90 91 module.finish(); 92 } 93 94 #[test] 95 fn switch_error() { 96 use cranelift_codegen::settings; 97 98 let sig = Signature { 99 params: vec![AbiParam::new(types::I32)], 100 returns: vec![AbiParam::new(types::I32)], 101 call_conv: CallConv::SystemV, 102 }; 103 104 let mut func = Function::with_name_signature(UserFuncName::default(), sig); 105 let mut func_ctx = FunctionBuilderContext::new(); 106 { 107 let mut bcx: FunctionBuilder = FunctionBuilder::new(&mut func, &mut func_ctx); 108 let start = bcx.create_block(); 109 let bb0 = bcx.create_block(); 110 let bb1 = bcx.create_block(); 111 let bb2 = bcx.create_block(); 112 let bb3 = bcx.create_block(); 113 println!("{start} {bb0} {bb1} {bb2} {bb3}"); 114 115 bcx.declare_var(types::I32); 116 bcx.declare_var(types::I32); 117 let in_val = bcx.append_block_param(start, types::I32); 118 bcx.switch_to_block(start); 119 bcx.def_var(Variable::new(0), in_val); 120 bcx.ins().jump(bb0, &[]); 121 122 bcx.switch_to_block(bb0); 123 let discr = bcx.use_var(Variable::new(0)); 124 let mut switch = cranelift_frontend::Switch::new(); 125 for &(index, bb) in &[ 126 (9, bb1), 127 (13, bb1), 128 (10, bb1), 129 (92, bb1), 130 (39, bb1), 131 (34, bb1), 132 ] { 133 switch.set_entry(index, bb); 134 } 135 switch.emit(&mut bcx, discr, bb2); 136 137 bcx.switch_to_block(bb1); 138 let v = bcx.use_var(Variable::new(0)); 139 bcx.def_var(Variable::new(1), v); 140 bcx.ins().jump(bb3, &[]); 141 142 bcx.switch_to_block(bb2); 143 let v = bcx.use_var(Variable::new(0)); 144 bcx.def_var(Variable::new(1), v); 145 bcx.ins().jump(bb3, &[]); 146 147 bcx.switch_to_block(bb3); 148 let r = bcx.use_var(Variable::new(1)); 149 bcx.ins().return_(&[r]); 150 151 bcx.seal_all_blocks(); 152 bcx.finalize(); 153 } 154 155 let flags = settings::Flags::new(settings::builder()); 156 match cranelift_codegen::verify_function(&func, &flags) { 157 Ok(_) => {} 158 Err(err) => { 159 let pretty_error = 160 cranelift_codegen::print_errors::pretty_verifier_error(&func, None, err); 161 panic!("pretty_error:\n{pretty_error}"); 162 } 163 } 164 } 165 166 #[test] 167 fn libcall_function() { 168 let flag_builder = settings::builder(); 169 let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap(); 170 let isa = isa_builder 171 .finish(settings::Flags::new(flag_builder)) 172 .unwrap(); 173 let mut module = 174 ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap()); 175 176 let sig = Signature { 177 params: vec![], 178 returns: vec![], 179 call_conv: CallConv::SystemV, 180 }; 181 182 let func_id = module 183 .declare_function("function", Linkage::Local, &sig) 184 .unwrap(); 185 186 let mut ctx = Context::new(); 187 ctx.func = Function::with_name_signature(UserFuncName::user(0, func_id.as_u32()), sig); 188 let mut func_ctx = FunctionBuilderContext::new(); 189 { 190 let mut bcx: FunctionBuilder = FunctionBuilder::new(&mut ctx.func, &mut func_ctx); 191 let block = bcx.create_block(); 192 bcx.switch_to_block(block); 193 194 let int = module.target_config().pointer_type(); 195 let zero = bcx.ins().iconst(I16, 0); 196 let size = bcx.ins().iconst(int, 10); 197 198 let mut signature = module.make_signature(); 199 signature.params.push(AbiParam::new(int)); 200 signature.returns.push(AbiParam::new(int)); 201 let callee = module 202 .declare_function("malloc", Linkage::Import, &signature) 203 .expect("declare malloc function"); 204 let local_callee = module.declare_func_in_func(callee, &mut bcx.func); 205 let argument_exprs = vec![size]; 206 let call = bcx.ins().call(local_callee, &argument_exprs); 207 let buffer = bcx.inst_results(call)[0]; 208 209 bcx.call_memset(module.target_config(), buffer, zero, size); 210 211 bcx.ins().return_(&[]); 212 } 213 214 module.define_function(func_id, &mut ctx).unwrap(); 215 216 module.finish(); 217 } 218 219 #[test] 220 #[should_panic(expected = "has a null byte, which is disallowed")] 221 fn reject_nul_byte_symbol_for_func() { 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 225 .finish(settings::Flags::new(flag_builder)) 226 .unwrap(); 227 let mut module = 228 ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap()); 229 230 let sig = Signature { 231 params: vec![], 232 returns: vec![], 233 call_conv: CallConv::SystemV, 234 }; 235 236 let _ = module 237 .declare_function("function\u{0}with\u{0}nul\u{0}bytes", Linkage::Local, &sig) 238 .unwrap(); 239 } 240 241 #[test] 242 #[should_panic(expected = "has a null byte, which is disallowed")] 243 fn reject_nul_byte_symbol_for_data() { 244 let flag_builder = settings::builder(); 245 let isa_builder = cranelift_codegen::isa::lookup_by_name("x86_64-unknown-linux-gnu").unwrap(); 246 let isa = isa_builder 247 .finish(settings::Flags::new(flag_builder)) 248 .unwrap(); 249 let mut module = 250 ObjectModule::new(ObjectBuilder::new(isa, "foo", default_libcall_names()).unwrap()); 251 252 let _ = module 253 .declare_data( 254 "data\u{0}with\u{0}nul\u{0}bytes", 255 Linkage::Local, 256 /* writable = */ true, 257 /* tls = */ false, 258 ) 259 .unwrap(); 260 } 261