diff --git a/cranelift/object/Cargo.toml b/cranelift/object/Cargo.toml index c8ee871ed50a..1656b40c1533 100644 --- a/cranelift/object/Cargo.toml +++ b/cranelift/object/Cargo.toml @@ -25,4 +25,4 @@ log = { workspace = true } [dev-dependencies] cranelift-frontend = { workspace = true } cranelift-entity = { workspace = true } -cranelift-codegen = { workspace = true, features = ["x86"] } +cranelift-codegen = { workspace = true, features = ["x86", "arm64"] } diff --git a/cranelift/object/src/backend.rs b/cranelift/object/src/backend.rs index 0d0eaefb7b8b..3821a1c223f7 100644 --- a/cranelift/object/src/backend.rs +++ b/cranelift/object/src/backend.rs @@ -847,6 +847,28 @@ impl ObjectModule { }, _ => unimplemented!("Aarch64Ld64GotLo12Nc is not supported for this file format"), }, + Reloc::Aarch64AdrPrelPgHi21 => match self.object.format() { + object::BinaryFormat::Elf => RelocationFlags::Elf { + r_type: object::elf::R_AARCH64_ADR_PREL_PG_HI21, + }, + object::BinaryFormat::MachO => RelocationFlags::MachO { + r_type: object::macho::ARM64_RELOC_PAGE21, + r_pcrel: true, + r_length: 2, + }, + _ => unimplemented!("Aarch64AdrPrelPgHi21 is not supported for this file format"), + }, + Reloc::Aarch64AddAbsLo12Nc => match self.object.format() { + object::BinaryFormat::Elf => RelocationFlags::Elf { + r_type: object::elf::R_AARCH64_ADD_ABS_LO12_NC, + }, + object::BinaryFormat::MachO => RelocationFlags::MachO { + r_type: object::macho::ARM64_RELOC_PAGEOFF12, + r_pcrel: false, + r_length: 2, + }, + _ => unimplemented!("Aarch64AddAbsLo12Nc is not supported for this file format"), + }, Reloc::S390xPCRel32Dbl => RelocationFlags::Generic { kind: RelocationKind::Relative, encoding: RelocationEncoding::S390xDbl, diff --git a/cranelift/object/tests/basic.rs b/cranelift/object/tests/basic.rs index 89f05faaa208..bdc03886a474 100644 --- a/cranelift/object/tests/basic.rs +++ b/cranelift/object/tests/basic.rs @@ -258,3 +258,54 @@ fn reject_nul_byte_symbol_for_data() { ) .unwrap(); } + +#[test] +fn aarch64_colocated_data_symbol_reloc() { + let flag_builder = settings::builder(); + let isa_builder = cranelift_codegen::isa::lookup_by_name("aarch64-unknown-linux-gnu").unwrap(); + let isa = isa_builder + .finish(settings::Flags::new(flag_builder)) + .unwrap(); + let mut module = + ObjectModule::new(ObjectBuilder::new(isa, "test", default_libcall_names()).unwrap()); + + let data_id = module + .declare_data("my_data", Linkage::Local, true, false) + .unwrap(); + + let mut data_desc = DataDescription::new(); + data_desc.define_zeroinit(64); + module.define_data(data_id, &data_desc).unwrap(); + + let sig = Signature { + params: vec![], + returns: vec![AbiParam::new(types::I64)], + call_conv: CallConv::SystemV, + }; + + let func_id = module + .declare_function("load_data_addr", Linkage::Local, &sig) + .unwrap(); + + let mut ctx = Context::new(); + ctx.func = Function::with_name_signature(UserFuncName::user(0, func_id.as_u32()), sig); + let mut func_ctx = FunctionBuilderContext::new(); + { + let mut bcx: FunctionBuilder = FunctionBuilder::new(&mut ctx.func, &mut func_ctx); + let block = bcx.create_block(); + bcx.switch_to_block(block); + + let gv = module.declare_data_in_func(data_id, &mut bcx.func); + let ptr = module.target_config().pointer_type(); + let addr = bcx.ins().global_value(ptr, gv); + bcx.ins().return_(&[addr]); + + bcx.seal_all_blocks(); + bcx.finalize(); + } + + module.define_function(func_id, &mut ctx).unwrap(); + + let product = module.finish(); + product.emit().expect("emit object file"); +}