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