-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Cranelift: implement PIC relocations on AArch64 #2907
Copy link
Copy link
Closed
Labels
bugIncorrect behavior in the current implementation that needs fixingIncorrect behavior in the current implementation that needs fixingcraneliftIssues related to the Cranelift code generatorIssues related to the Cranelift code generatorcranelift:area:aarch64Issues related to AArch64 backend.Issues related to AArch64 backend.
Description
Cranelift emits AbsoluteRelocation Reloc::Abs8 when is_pic setting is enabled in architecture aarch64
Steps to Reproduce
(module
;; Recursive factorial
(func (export "fac-rec") (param i64) (result i64)
(if (result i64) (i64.eq (local.get 0) (i64.const 0))
(then (i64.const 1))
(else
(i64.mul (local.get 0) (call 0 (i64.sub (local.get 0) (i64.const 1))))
)
)
)
)$ wasmtime wasm2obj fac.wat fac.oCode emitted fac.o has absolute relocations.
Expected Results
Is expected for Cranelift to emit a relative relocation for aarch64 when is_pic is enabled.
Actual Results
Code emitted with an absolute relocation.
Versions and Environment
Cranelift version: cranelift-codegen = "0.73.0"
Operating system: Any
Architecture: Aarch64
Extra info
Here's where the wrong code is emitted:
wasmtime/cranelift/codegen/src/isa/aarch64/inst/emit.rs
Lines 2440 to 2462 in 207da98
| &Inst::LoadExtName { | |
| rd, | |
| ref name, | |
| offset, | |
| } => { | |
| let inst = Inst::ULoad64 { | |
| rd, | |
| mem: AMode::Label(MemLabel::PCRel(8)), | |
| flags: MemFlags::trusted(), | |
| }; | |
| inst.emit(sink, emit_info, state); | |
| let inst = Inst::Jump { | |
| dest: BranchTarget::ResolvedOffset(12), | |
| }; | |
| inst.emit(sink, emit_info, state); | |
| let srcloc = state.cur_srcloc(); | |
| sink.add_reloc(srcloc, Reloc::Abs8, name, offset); | |
| if emit_info.flags().emit_all_ones_funcaddrs() { | |
| sink.put8(u64::max_value()); | |
| } else { | |
| sink.put8(0); | |
| } | |
| } |
In the new x86 backend however, the is_pic case is properly handled:
wasmtime/cranelift/codegen/src/isa/x64/inst/emit.rs
Lines 2350 to 2387 in e676589
| Inst::LoadExtName { dst, name, offset } => { | |
| if info.flags().is_pic() { | |
| // Generates: movq symbol@GOTPCREL(%rip), %dst | |
| let enc_dst = int_reg_enc(dst.to_reg()); | |
| sink.put1(0x48 | ((enc_dst >> 3) & 1) << 2); | |
| sink.put1(0x8B); | |
| sink.put1(0x05 | ((enc_dst & 7) << 3)); | |
| emit_reloc(sink, state, Reloc::X86GOTPCRel4, name, -4); | |
| sink.put4(0); | |
| // Offset in the relocation above applies to the address of the *GOT entry*, not | |
| // the loaded address; so we emit a separate add or sub instruction if needed. | |
| if *offset < 0 { | |
| assert!(*offset >= -i32::MAX as i64); | |
| sink.put1(0x48 | ((enc_dst >> 3) & 1)); | |
| sink.put1(0x81); | |
| sink.put1(0xe8 | (enc_dst & 7)); | |
| sink.put4((-*offset) as u32); | |
| } else if *offset > 0 { | |
| assert!(*offset <= i32::MAX as i64); | |
| sink.put1(0x48 | ((enc_dst >> 3) & 1)); | |
| sink.put1(0x81); | |
| sink.put1(0xc0 | (enc_dst & 7)); | |
| sink.put4(*offset as u32); | |
| } | |
| } else { | |
| // The full address can be encoded in the register, with a relocation. | |
| // Generates: movabsq $name, %dst | |
| let enc_dst = int_reg_enc(dst.to_reg()); | |
| sink.put1(0x48 | ((enc_dst >> 3) & 1)); | |
| sink.put1(0xB8 | (enc_dst & 7)); | |
| emit_reloc(sink, state, Reloc::Abs8, name, *offset); | |
| if info.flags().emit_all_ones_funcaddrs() { | |
| sink.put8(u64::max_value()); | |
| } else { | |
| sink.put8(0); | |
| } | |
| } | |
| } |
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugIncorrect behavior in the current implementation that needs fixingIncorrect behavior in the current implementation that needs fixingcraneliftIssues related to the Cranelift code generatorIssues related to the Cranelift code generatorcranelift:area:aarch64Issues related to AArch64 backend.Issues related to AArch64 backend.