Skip to content

Commit

Permalink
Changed how relocations are handled in singlepass/aarch64
Browse files Browse the repository at this point in the history
  • Loading branch information
ptitSeb committed Feb 22, 2022
1 parent 81afc23 commit b7d705a
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 44 deletions.
9 changes: 5 additions & 4 deletions lib/compiler-singlepass/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2598,17 +2598,18 @@ impl<'a, M: Machine> FuncGen<'a, M> {
function_index - self.module.num_imported_functions,
))
};
self.machine
.move_with_reloc(reloc_target, &mut self.relocations);
let calling_convention = self.calling_convention;

self.emit_call_native(
|this| {
let offset = this
.machine
.mark_instruction_with_trap_code(TrapCode::StackOverflow);
this.machine
.emit_call_register(this.machine.get_grp_for_call());
let mut relocations = this
.machine
.emit_call_with_reloc(calling_convention, reloc_target);
this.machine.mark_instruction_address_end(offset);
this.relocations.append(&mut relocations);
},
params.iter().copied(),
param_types.iter().copied(),
Expand Down
17 changes: 17 additions & 0 deletions lib/compiler-singlepass/src/emitter_arm64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,10 @@ pub trait EmitterARM64 {
fn emit_clz(&mut self, sz: Size, src: Location, dst: Location);
fn emit_rbit(&mut self, sz: Size, src: Location, dst: Location);

fn emit_nop(&mut self);
fn emit_label(&mut self, label: Label);
fn emit_load_label(&mut self, reg: GPR, label: Label);
fn emit_ldr_label(&mut self, size: Size, reg: GPR, label: Label);
fn emit_b_label(&mut self, label: Label);
fn emit_cbz_label(&mut self, sz: Size, reg: Location, label: Label);
fn emit_cbnz_label(&mut self, sz: Size, reg: Location, label: Label);
Expand Down Expand Up @@ -1892,13 +1894,28 @@ impl EmitterARM64 for Assembler {
}
}

fn emit_nop(&mut self) {
dynasm!(self ; nop);
}
fn emit_label(&mut self, label: Label) {
dynasm!(self ; => label);
}
fn emit_load_label(&mut self, reg: GPR, label: Label) {
let reg = reg.into_index() as u32;
dynasm!(self ; adr X(reg), =>label);
}
fn emit_ldr_label(&mut self, size: Size, reg: GPR, label: Label) {
let reg = reg.into_index() as u32;
match size {
Size::S32 => dynasm!(self ; ldr W(reg), =>label),
Size::S64 => dynasm!(self ; ldr X(reg), =>label),
_ => panic!(
"singlepass can't emit LDR {:?} {:?} => {:?} ",
size, reg, label
),
}
}

fn emit_b_label(&mut self, label: Label) {
dynasm!(self ; b =>label);
}
Expand Down
6 changes: 3 additions & 3 deletions lib/compiler-singlepass/src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1038,11 +1038,11 @@ pub trait Machine {
);

/// emit a move function address to GPR ready for call, using appropriate relocation
fn move_with_reloc(
fn emit_call_with_reloc(
&mut self,
calling_convention: CallingConvention,
reloc_target: RelocationTarget,
relocations: &mut Vec<Relocation>,
);
) -> Vec<Relocation>;
/// Add with location directly from the stack
fn emit_binop_add64(
&mut self,
Expand Down
38 changes: 9 additions & 29 deletions lib/compiler-singlepass/src/machine_arm64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3229,43 +3229,23 @@ impl Machine for MachineARM64 {
unimplemented!();
}

fn move_with_reloc(
fn emit_call_with_reloc(
&mut self,
_calling_convention: CallingConvention,
reloc_target: RelocationTarget,
relocations: &mut Vec<Relocation>,
) {
let reloc_at = self.assembler.get_offset().0;
relocations.push(Relocation {
kind: RelocationKind::Arm64Movw0,
reloc_target,
offset: reloc_at as u32,
addend: 0,
});
self.assembler.emit_movz(Location::GPR(GPR::X27), 0);
let reloc_at = self.assembler.get_offset().0;
relocations.push(Relocation {
kind: RelocationKind::Arm64Movw1,
reloc_target,
offset: reloc_at as u32,
addend: 0,
});
self.assembler.emit_movk(Location::GPR(GPR::X27), 0, 16);
let reloc_at = self.assembler.get_offset().0;
relocations.push(Relocation {
kind: RelocationKind::Arm64Movw2,
reloc_target,
offset: reloc_at as u32,
addend: 0,
});
self.assembler.emit_movk(Location::GPR(GPR::X27), 0, 32);
) -> Vec<Relocation> {
let mut relocations = vec![];
let next = self.get_label();
let reloc_at = self.assembler.get_offset().0;
self.assembler.emit_call_label(next);
self.emit_label(next);
relocations.push(Relocation {
kind: RelocationKind::Arm64Movw3,
kind: RelocationKind::Arm64Call,
reloc_target,
offset: reloc_at as u32,
addend: 0,
});
self.assembler.emit_movk(Location::GPR(GPR::X27), 0, 48);
relocations
}

fn emit_binop_add64(&mut self, loc_a: Location, loc_b: Location, ret: Location) {
Expand Down
9 changes: 6 additions & 3 deletions lib/compiler-singlepass/src/machine_x64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3869,13 +3869,14 @@ impl Machine for MachineX86_64 {
self.release_gpr(compare);
}

fn move_with_reloc(
fn emit_call_with_reloc(
&mut self,
_calling_convention: CallingConvention,
reloc_target: RelocationTarget,
relocations: &mut Vec<Relocation>,
) {
) -> Vec<Relocation> {
let reloc_at = self.assembler.get_offset().0 + self.assembler.arch_mov64_imm_offset();

let mut relocations = vec![];
relocations.push(Relocation {
kind: RelocationKind::Abs8,
reloc_target,
Expand All @@ -3890,6 +3891,8 @@ impl Machine for MachineX86_64 {
Location::Imm64(std::u64::MAX),
Location::GPR(GPR::RAX),
);
self.assembler.emit_call_register(GPR::RAX);
relocations
}

fn emit_binop_add64(&mut self, loc_a: Location, loc_b: Location, ret: Location) {
Expand Down
2 changes: 1 addition & 1 deletion lib/engine-universal/src/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ fn apply_relocation(
)
}
let reloc_delta = (((reloc_delta / 4) as u32) & 0x3ff_ffff)
| read_unaligned(reloc_address as *mut u32);
| (read_unaligned(reloc_address as *mut u32) & 0xfc00_0000);
write_unaligned(reloc_address as *mut u32, reloc_delta);
},
RelocationKind::Arm64Movw0 => unsafe {
Expand Down
60 changes: 58 additions & 2 deletions lib/object/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,8 @@ pub fn emit_compilation(
let (_symbol_id, section_offset) = obj.symbol_section_and_offset(symbol_id).unwrap();

for r in relocations {
let relocation_address = section_offset + r.offset as u64;

let (relocation_kind, relocation_encoding, relocation_size) = match r.kind {
Reloc::Abs4 => (RelocationKind::Absolute, RelocationEncoding::Generic, 32),
Reloc::Abs8 => (RelocationKind::Absolute, RelocationEncoding::Generic, 64),
Expand Down Expand Up @@ -309,6 +311,62 @@ pub fn emit_compilation(
RelocationEncoding::Generic,
32,
),
Reloc::Arm64Movw0 => (
match obj.format() {
object::BinaryFormat::Elf => {
RelocationKind::Elf(elf::R_AARCH64_MOVW_UABS_G0)
}
fmt => panic!(
"unsupported binary format {:?} for relocation {:?}",
fmt,
obj.format()
),
},
RelocationEncoding::Generic,
16,
),
Reloc::Arm64Movw1 => (
match obj.format() {
object::BinaryFormat::Elf => {
RelocationKind::Elf(elf::R_AARCH64_MOVW_UABS_G1)
}
fmt => panic!(
"unsupported binary format {:?} for relocation {:?}",
fmt,
obj.format()
),
},
RelocationEncoding::Generic,
16,
),
Reloc::Arm64Movw2 => (
match obj.format() {
object::BinaryFormat::Elf => {
RelocationKind::Elf(elf::R_AARCH64_MOVW_UABS_G2)
}
fmt => panic!(
"unsupported binary format {:?} for relocation {:?}",
fmt,
obj.format()
),
},
RelocationEncoding::Generic,
16,
),
Reloc::Arm64Movw3 => (
match obj.format() {
object::BinaryFormat::Elf => {
RelocationKind::Elf(elf::R_AARCH64_MOVW_UABS_G3)
}
fmt => panic!(
"unsupported binary format {:?} for relocation {:?}",
fmt,
obj.format()
),
},
RelocationEncoding::Generic,
16,
),
other => {
return Err(ObjectError::UnsupportedArchitecture(format!(
"{} (relocation: {}",
Expand All @@ -317,8 +375,6 @@ pub fn emit_compilation(
}
};

let relocation_address = section_offset + r.offset as u64;

match r.reloc_target {
RelocationTarget::LocalFunc(index) => {
let (_, target_symbol) = function_symbol_ids.get(index).unwrap();
Expand Down
2 changes: 1 addition & 1 deletion lib/vm/src/trap/handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ int wasmer_register_setjmp(
void **buf_storage,
void (*body)(void*),
void *payload) {
#if 0 && defined(CFG_TARGET_OS_MACOS)
#if 1 && defined(CFG_TARGET_OS_MACOS)
// Enable this block to ba able to debug Segfault with lldb
// This will mask the EXC_BAD_ACCESS from lldb...
static int allow_bad_access = 0;
Expand Down
2 changes: 1 addition & 1 deletion tests/ignores.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
singlepass spec::multi_value # Singlepass has not implemented multivalue (functions that returns "structs"/"tuples")
singlepass spec::simd # Singlepass doesn't support yet SIMD (no one asked for this feature)

singlepass+dylib+aarch64 *
singlepass+dylib+aarch64+macos *
windows+dylib * # This might be trivial to fix?
musl+dylib * # Dynamic loading not supported in Musl

Expand Down

0 comments on commit b7d705a

Please sign in to comment.